Skip to main content

plot/lib/logic/path/
path_canonical_ctx.rs

1use std::{
2	env,
3	fs,
4	path::{Path, PathBuf},
5};
6
7use anyhow::{Context, Result};
8
9/// Reprezentacja pojedynczego węzła ścieżki (buf + string)
10#[derive(Debug, Clone)]
11pub struct PathNode {
12	pub buf: PathBuf,
13	pub str: String,
14}
15
16fn normalize_path<P: AsRef<Path>>(p: P) -> String {
17	p.as_ref().to_string_lossy().trim_start_matches(r"\\?\").replace('\\', "/")
18}
19
20impl PathNode {
21	pub fn new(buf: PathBuf) -> Self {
22		let str = normalize_path(&buf);
23		Self { buf, str }
24	}
25}
26
27/// Relacja między katalogiem wykonania a katalogiem docelowym
28#[derive(Debug, Clone)]
29pub struct AnchoredPathsDatum {
30	pub execut_dir: PathNode,
31	pub select_dir: PathNode,
32	pub relat_path: String,
33}
34
35impl AnchoredPathsDatum {
36	pub fn new<P: AsRef<Path>>(input: P) -> Result<Self> {
37		let input = input.as_ref();
38
39		let execut_dir_buf = env::current_dir().context("Nie można odczytać katalogu roboczego (CWD)")?;
40
41		let select_dir_buf = fs::canonicalize(input)
42			.with_context(|| format!("Nie można ustalić ścieżki '{}'", input.to_string_lossy()))?;
43
44		let relat_path = match select_dir_buf.strip_prefix(&execut_dir_buf) {
45			Ok(rel) => {
46				let s = rel.to_string_lossy().replace('\\', "/");
47				if s.is_empty() { "./".to_string() } else { format!("./{}/", s) }
48			}
49			Err(_) => normalize_path(input),
50		};
51
52		Ok(Self { execut_dir: PathNode::new(execut_dir_buf), select_dir: PathNode::new(select_dir_buf), relat_path })
53	}
54}