kodept_core/
file_relative.rs

1use std::fmt::Formatter;
2use std::path::{Path, PathBuf};
3
4use crate::code_source::CodeSource;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum CodePath {
8    ToFile(PathBuf),
9    ToMemory(String),
10}
11
12#[derive(Debug)]
13pub struct FileRelative<T> {
14    pub value: T,
15    pub filepath: CodePath,
16}
17
18impl CodeSource {
19    pub fn with_filename<T>(&self, f: impl Fn(&Self) -> T) -> FileRelative<T> {
20        FileRelative {
21            value: f(self),
22            filepath: self.path(),
23        }
24    }
25
26    #[must_use]
27    pub fn path(&self) -> CodePath {
28        match self {
29            CodeSource::Memory { name, .. } => CodePath::ToMemory(name.clone()),
30            CodeSource::File { name, .. } => CodePath::ToFile(name.clone()),
31        }
32    }
33}
34
35impl<T> FileRelative<T> {
36    pub fn map<V>(self, f: impl FnOnce(T) -> V) -> FileRelative<V> {
37        FileRelative {
38            value: f(self.value),
39            filepath: self.filepath,
40        }
41    }
42}
43
44impl CodePath {
45    pub fn get_relative_path<P: AsRef<Path> + ?Sized>(&self, base: &P) -> CodePath {
46        match self {
47            CodePath::ToFile(p) => {
48                CodePath::ToFile(pathdiff::diff_paths(p, base).unwrap_or(p.clone()))
49            }
50            CodePath::ToMemory(s) => CodePath::ToMemory(s.clone()),
51        }
52    }
53}
54
55impl std::fmt::Display for CodePath {
56    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
57        match self {
58            CodePath::ToFile(p) => write!(f, "{0}", p.display()),
59            CodePath::ToMemory(p) => write!(f, "{p}"),
60        }
61    }
62}