Is it possible to access current file name in Rust by
// main.rs
fn main() {
println!("filename: {}", FILE_NAME);
}
?
(This program should print filename: main.rs)
You can use the std::file macro to get the current source filename at the compile time.
let this_file = file!();
If you want to remove the path from the returned filename, you can construct a Path with it and call the file_name method.
let filename_only = Path::new(this_file).file_name().and_then(|s| s.to_str()).unwrap();
Playground
Related
I want to create a std::process::Command and check whether an executable actually exists at that location before actually spawning the Command later. What would be the pragmatic way to do this?
I have this code:
let c = std::process::Command::new("my_exe");
// something here
c.spawn().unwrap();
I want to be able to validate the my_exe path when creating the Command and then spawn way later.
check whether an executable actually exists at that location before actually spawning the Command.
Don't as that's a time-of-check to time-of-use race condition. Instead, check the error value from executing the Command: Check if a command is in PATH/executable as process.
If you want to check if a file is present in the working directory, you can use Path::exists, as described in How to check whether a path exists?.
Also, Command::spawn() takes a mutable reference to self so c needs to be mutable.
use std::path::Path;
use std::process::Command;
if Path::new("PATH_TO_EXECUTABLE").exists() {
let mut c = Command::new("PATH_TO_EXECUTABLE");
// do something
c.spawn().unwrap();
}
Use the is_executable crate:
use is_executable::IsExecutable;
use std::fs;
let paths = fs::read_dir("./").unwrap();
for path in paths {
let file_path = path.unwrap().path();
if file_path.is_executable() {
println!("File: {:?} is executable!", file_path);
} else {
println!("File: {:?} is _not_ executable!", file_path);
}
}
Working with Rust and Rocket here. I have an endpoint to upload one file at a time with form-data:
use rocket::form::{Form, FromForm};
use rocket::fs::TempFile;
use std::ffi::OsStr;
use std::path::{Path};
use uuid::Uuid;
#[post("/file_upload", format = "multipart/form-data", data = "<form>")]
pub async fn file_upload(mut form: Form<Upload<'_>>) -> std::io::Result<String> {
// Get raw file
let file_name = form.file.raw_name().unwrap().dangerous_unsafe_unsanitized_raw().as_str();name
// Get extension of file name
let extension = Path::new(file_name).extension().and_then(OsStr::to_str).unwrap();
// Generate new UUID
let id: String = Uuid::new_v4().to_string();
// Build path to save file
let file_path = String::from("media/temp_files") + "/" + &id + "." + extension;
// Save file
form.file.persist_to(file_path).await?;
Ok(String::from("Ok"))
}
This works, but I am mixing persistence, business logic and http infrastructure in the same module.
I want to rely on Rocket only to retrieve the file stream and metadata (file name, size and content type), and pass it to another function that would be in charge or validation, image processing, etc.
I have access to the metadata, but I don't know how to retrieve the Buffered content from the TempFile struct.
// rocket-0.5.0-rc.2/src/fs/temp_file.rs
[…]
pub enum TempFile<'v> {
#[doc(hidden)]
File {
file_name: Option<&'v FileName>,
content_type: Option<ContentType>,
path: Either<TempPath, PathBuf>,
len: u64,
},
#[doc(hidden)]
Buffered {
content: &'v str,
}
}
[…]
I don't see any method returning it.Is there any method I'm missing to retrieve the raw file content? Or maybe there is a different struct/trait in Rocket to achieve this.
This is my folder structure.
src
├── main.rs
└── assembly_files
└── toyRISC.asm
Why is this not enough or where is the error?
I tried with raw &str:
let filename = "./assembly_files/toyRISC.asm";
let result = fs::read_to_string(path).expect("Please provide valid file name");
Also tried using Path and OsStr , shown in code below.
// main.rs
use std::{ffi::OsStr, fs, path::Path};
fn main() {
let filename = "assembly_files/toyRISC.asm";
let path = Path::new("./assembly_files/toyRISC.asm");
println!("{:?}", path);
let result = fs::read_to_string(path).expect("Please provide valid file name");
}
This is the error
thread 'main' panicked at 'Please provide valid file name: Os { code: 3, kind: NotFound, message: "The system cannot find the path specified."
}', src\main.rs:6:43
When you create a relative Path to a file, e.g. Path::new("./assembly_files/toyRISC.asm"); the path is relative to the folder from which you call the executable. Note that this isn't necessarily the folder where the executable is stored!
If you simply run cargo run at the root of your project to run it, then you need to change the path to Path::new("./src/assembly_files/toyRISC.asm");
I using rust to create a folder in ~, however when my code runs the directory is created inside my project's folder instead in ~.
My code:
use std::fs::create_dir_all;
use std::path::Path;
fn main() {
let path = Path::new("~/.hidden_folder");
match create_dir_all(path) {
Ok(f) => {
println!("created folder")
},
Err(err) => {
println!("{:?}", err);
}
};
}
Any idea how to create the folder in the correct directory ?
If you want your home directory, I recommend using this crate or specifying the absolute path. If you want to save it in any other directories, just use relative or absolute paths, but don't use ~ because Rust doesn't know the context of ~.
If I call .to_path_buf() immediately after expect, the temporary directory will not be created. Is this a bug or a Rust feature?
extern crate mktemp;
use std::path::Path;
fn main() {
let temp_dir = mktemp::Temp::new_dir().expect("Failed to create a temp directory");
let temp_dir_path = temp_dir.to_path_buf();
println!("tmp path exists: {}", Path::exists(&temp_dir_path));
let temp_dir_path = mktemp::Temp::new_dir().expect("Failed to create a temp directory").to_path_buf();
println!("tmp path exists: {}", Path::exists(&temp_dir_path));
}
Which outputs:
tmp path exists: true
tmp path exists: false
I don't know, but I wonder if there's something in the mktemp documentation about this...
Once the variable goes out of scope, the underlying file system resource is removed.
You're not storing the Temp in a variable, so it goes out of scope immediately. It's creating the directory and then immediately destroying it.