Hello there!
I need a little help with a thing, havent found it on docs.
I need to retrieve as a str the reverse relative given two Path, as example:
Dir 1: /root/folder/subfolder/subsubfolder
Dir 2: /root/folder
To "go" from Dir2 to dir1 is ../../
I need a function or method with the "reverse" from dir1 to 2, that is:
./subfolder/subsubfolder.
Or the opposite, too, like
StrReverse = reverseRelativePath(Dir1, dir2);
It looks like what you want is to use Path::parent twice.
let my_path = Path::new("/root/folder/subfolder/subsubfolder");
let grandparent = my_path.parent()?.parent()?;
assert_eq!(Path::new("/root/folder", my_path));
pub fn relative(from: &Path, to: &Path) -> PathBuf {
let common = from
.components()
.zip(to.components())
.take_while(|(a, b)| a == b)
.count();
from.components()
.skip(common)
.map(|_| Component::ParentDir)
.chain(to.components().skip(common))
.collect()
}
Guys you need to stop that... I was waiting an answer, once, maybe in 4 to 5 months blaming me lol. That community is great as told so!
Something alike that, thats the closest i`ve come
use std::path::{Component, Path, PathBuf};
pub fn relative(from: &Path, to: &Path) -> PathBuf {
let common = from
.components()
.zip(to.components())
.take_while(|(a, b)| a == b)
.count();
let mut res = PathBuf::new();
for c in from
.components()
.skip(common)
.map(|_| Component::ParentDir)
.chain(to.components().skip(common))
{
res.push(c);
}
res
}
fn main() {
println!(
"{:?}",
relative(
&"/root/folder/suba0".parse::<PathBuf>().unwrap(),
&"/root/folder/subb0/suba1/suba2".parse::<PathBuf>().unwrap(),
//&"/root/folder/subb0".parse::<PathBuf>().unwrap(),
)
)
}
got "../subb0/suba1/suba2"
now i can append a "/" at the end to get the "../subb0/suba1/suba2" i wanted. At least a modification in code do better.
// Does the same as canonicalize() but without needing the file to exist
fn canonical_path(path: &Path) -> PathBuf {
let mut result = PathBuf::new();
for component in path.components() {
match component {
Component::CurDir => continue,
Component::ParentDir => {
result.pop();
}
_ => result.push(component),
}
}
result
}
// the call REQUIRES ALREADY MADE &from_path.canonicalize()?,
fn reverse_relative_path(from: &Path, to: &Path) -> PathBuf {
let path_to = canonical_path(to);
let common = path_to
.components()
.zip(from.components())
.take_while(|(a, b)| a == b)
.count();
let mut res = PathBuf::new();
let mut skip_first_parent = true;
for c in path_to
.components()
.skip(common)
.map(|_| Component::ParentDir)
.chain(from.components().skip(common))
{
if skip_first_parent && c == Component::ParentDir {
skip_first_parent = false;
continue;
}
res.push(c);
}
res
}
Like, from ".\src" to ".\target" : "..\src" think something like: i am at the terminal prompt, and go from src to target: cd .. cd target
so, what i need to do to go "back" to src? cd ..
*cd \src*