How to read file from another(nested) folder? - rust

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");

Related

Is it possible to access current file name?

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

How to create a folder outside the poject directory in rust

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 ~.

Rust build script to copy a file to target directory

For my project, I would like to copy the file config.ron that is in the root of my project to the target directory when the project is built. I know that you can use include_str! to add the content of the file to the program at compile time, but I would like the file to stay in the root of the target folder so that it can be edited without the need to recompile the program.
I've currently been trying out a build script to accomplish this but I am have no luck.
use std::process::Command;
use std::env;
fn main() {
let profile = std::env::var("PROFILE").unwrap();
match profile.as_str() {
"debug" => {
Command::new("cmd")
.args(&["copy", "/y"])
.arg(&format!(r#"{}\config.ron"#, env::var("CARGO_MANIFEST_DIR").unwrap()))
.arg(&format!(r#"{}\target\debug"#, env::var("CARGO_MANIFEST_DIR").unwrap()))
.status()
.expect("Copy failed to execute.");
()
},
"release" => {
Command::new("cmd")
.args(&["copy", "/y"])
.arg(&format!(r#"{}\config.ron"#, env::var("CARGO_MANIFEST_DIR").unwrap()))
.arg(&format!(r#"{}\target\release"#, env::var("CARGO_MANIFEST_DIR").unwrap()))
.status()
.expect("Copy failed to execute.");
()
},
_ => (),
}
}
What would be the correct way to get this file copied to the target directory using a build script?
If you really want to do it in a build script, I would go with these ingredients:
OUT_DIR and CARGO_TARGET_DIR
std::fs::copy

Inconsistent behavior of `mktemp` crate in Rust

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.

Create relative symlinks using absolute paths in Node.JS

I have a projects with the following structure:
project-root
├── some-dir
│   ├── alice.json
│   ├── bob.json
│   └── dave.json
└── ...
I want to create symlinks like the following ones:
foo -> alice.json
I chose to use the fs.symlink function:
fs.symlink(srcpath, dstpath[, type], callback)
Asynchronous symlink(2). No arguments other than a possible exception are given to the completion callback. The type argument can be set to 'dir', 'file', or 'junction' (default is 'file') and is only available on Windows (ignored on other platforms). Note that Windows junction points require the destination path to be absolute. When using 'junction', the destination argument will automatically be normalized to absolute path.
So, I did:
require("fs").symlink(
projectRoot + "/some-dir/alice.json"
, projectRoot + "/some-dir/foo"
, function (err) { console.log(err || "Done."); }
);
This creates the foo symlink. However, since the paths are absolute the symlink uses absolute path as well.
How can I make the symlink path relative to a directory (in this case to some-dir)?
This will prevent errors when the parent directories are renamed or the project is moved on another machine.
The dirty alternative I see is using exec("ln -s alice.json foo", { cwd: pathToSomeDir }, callback);, but I would like to avoid that and use the NodeJS API.
So, how can I make relative symlinks using absolute paths in NodeJS?
Option 1: Use process.chdir() to change the current working directory of the process to projectRoot. Then, provide relative paths to fs.symlink().
Option 2: Use path.relative() or otherwise generate the relative path between your symlink and its target. Pass that relative path as the first argument to fs.symlink() while providing an absolute path for the second argument. For example:
var relativePath = path.relative('/some-dir', '/some-dir/alice.json');
fs.symlink(relativePath, '/some-dir/foo', callback);
const path = require('path');
const fs = require('fs');
// The actual symlink entity in the file system
const source = /* absolute path of source */;
// Where the symlink should point to
const absolute_target = /* absolute path of target */;
const target = path.relative(
path.dirname(source),
absolute_target
);
fs.symlink(
target,
source,
(err) => {
}
);

Resources