pub struct VaultPath { /* private fields */ }Expand description
A logical, vault-internal path to a note or directory.
VaultPath is the core’s single currency for everything inside a vault: it
never refers to a location outside the workspace, and it is portable across
Windows, macOS, and Linux. Components are sanitized and lowercased on
construction (see VaultPath::new) so that only characters valid on all
three filesystems survive and equality is effectively case-insensitive. The
separator is always PATH_SEPARATOR (/); translation to native OS paths
happens only at the filesystem boundary in nfs.
A path may be absolute (rooted at the vault root, rendered with a leading
/) or relative, and may contain ./.. components until flattened.
Implementations§
Source§impl VaultPath
impl VaultPath
Sourcepub fn new<S: AsRef<str>>(path: S) -> Self
pub fn new<S: AsRef<str>>(path: S) -> Self
Creates a new vault path, for every invalid character
it gets replaced to an underscore _. If you want to validate
the path first, either use the VaultPath::From trait or use
VaultPath::is_valid()
Sourcepub fn is_valid<S: AsRef<str>>(path: S) -> bool
pub fn is_valid<S: AsRef<str>>(path: S) -> bool
Returns true if path is already a clean vault path needing no
sanitization: every component is valid on all three target filesystems
and there are no doubled separators. Use this to validate caller-supplied
strings up front; VaultPath::new will instead silently repair them.
use kimun_core::nfs::VaultPath;
assert!(VaultPath::is_valid("/projects/notes.md"));
assert!(!VaultPath::is_valid("bad?name"));Sourcepub fn note_path_from<S: AsRef<str>>(path: S) -> Self
pub fn note_path_from<S: AsRef<str>>(path: S) -> Self
Builds a sanitized note path from path, ensuring it ends with the note
extension. A trailing separator is dropped before the extension is added,
so notes/ becomes notes.md. Unlike with_note_extension, the rest
of the string is sanitized through VaultPath::new, so this is the
correct constructor for real note paths (not search patterns).
use kimun_core::nfs::VaultPath;
assert_eq!(VaultPath::note_path_from("projects/todo").to_string(), "projects/todo.md");
assert_eq!(VaultPath::note_path_from("readme.md").to_string(), "readme.md");Sourcepub fn root() -> Self
pub fn root() -> Self
The vault root: an absolute path with no components, rendered as /.
use kimun_core::nfs::VaultPath;
assert_eq!(VaultPath::root().to_string(), "/");Sourcepub fn empty() -> Self
pub fn empty() -> Self
The empty relative path: no components and not absolute, rendered as the
empty string. Distinct from root, which is absolute.
use kimun_core::nfs::VaultPath;
assert_eq!(VaultPath::empty().to_string(), "");Sourcepub fn is_root_or_empty(&self) -> bool
pub fn is_root_or_empty(&self) -> bool
Returns true when the path has no components, i.e. it is either the
vault root or the empty path.
Sourcepub fn get_name_on_conflict(&self) -> VaultPath
pub fn get_name_on_conflict(&self) -> VaultPath
Returns a variant of this path with its final component’s name
incremented to avoid a collision. A numeric _N suffix is added or bumped
(e.g. note.md → note_0.md, note_0.md → note_1.md), preserving the
note extension. Used to pick a fresh name when the desired one is taken.
Sourcepub fn get_clean_name(&self) -> String
pub fn get_clean_name(&self) -> String
Returns the final component’s name with the note extension stripped — the
note’s display title as derived from its filename. For directories (no
extension) this is just the directory name. Compare get_name, which
keeps the extension.
use kimun_core::nfs::VaultPath;
assert_eq!(VaultPath::new("/projects/todo.md").get_clean_name(), "todo");Sourcepub fn to_bare_string(&self) -> String
pub fn to_bare_string(&self) -> String
Returns the full vault path as a string with the note extension stripped.
E.g. /projects/rust-notes.md → /projects/rust-notes
If the path does not end with the note extension, returns it unchanged.
Sourcepub fn to_string_with_ext(&self) -> String
pub fn to_string_with_ext(&self) -> String
Returns the full vault path as a string, ensuring it ends with the note extension.
E.g. /projects/rust-notes → /projects/rust-notes.md
If the path already ends with the extension, returns it unchanged.
Sourcepub fn get_slices(&self) -> Vec<String>
pub fn get_slices(&self) -> Vec<String>
Returns the path’s components as plain strings, after flattening
(so no ./.. entries remain). Useful for walking the path level by
level.
use kimun_core::nfs::VaultPath;
assert_eq!(VaultPath::new("/a/b/c.md").get_slices(), vec!["a", "b", "c.md"]);Sourcepub fn to_pathbuf<P: AsRef<Path>>(&self, workspace_path: P) -> PathBuf
pub fn to_pathbuf<P: AsRef<Path>>(&self, workspace_path: P) -> PathBuf
Joins this path onto workspace_path to produce the canonical on-disk
PathBuf, mapping / to native separators and flattening first.
This is the canonical (lowercase) location only; it does not perform
case-insensitive resolution, so an existing file stored under a different
case will not be found. Use the nfs resolver for that.
Sourcepub fn flatten(&self) -> VaultPath
pub fn flatten(&self) -> VaultPath
Returns a full path without any relative slices If it tries to go up beyond the current path, drops a warning
Sourcepub fn get_name(&self) -> String
pub fn get_name(&self) -> String
Returns the last part of the path slices if it is a note, will return the note filename, if it is a directory, will return the directory name
Sourcepub fn relative_link_from_note(&self, note_path: &VaultPath) -> VaultPath
pub fn relative_link_from_note(&self, note_path: &VaultPath) -> VaultPath
Returns the path of self written relative to a note file’s directory.
Markdown engines resolve relative links against the containing folder,
not the note file itself. Linking from /notes/journal/today.md to
/assets/img.png therefore produces ../../assets/img.png (two ..s
— for journal/ and notes/), not three. This wraps
Self::get_relative_to using the note’s parent path so callers get the
markdown-correct result.
Sourcepub fn resolve_link_in_note(&self, note_path: &VaultPath) -> VaultPath
pub fn resolve_link_in_note(&self, note_path: &VaultPath) -> VaultPath
Resolve self as a link target written inside note_path.
Inverse of Self::relative_link_from_note: markdown links resolve against
the directory containing the note, so a ../work/anton.md target in
/journal/today.md resolves to /work/anton.md (flattened, absolute).
Absolute targets are returned flattened as-is. A bare filename with no
directory part (e.g. anton.md) is returned unchanged so callers can
fall back to a vault-wide name lookup (wiki-style links).
Sourcepub fn get_relative_to(&self, reference_path: &VaultPath) -> VaultPath
pub fn get_relative_to(&self, reference_path: &VaultPath) -> VaultPath
Expresses this path relative to reference_path, walking up with ..
for each component of the reference not shared with this path, then down
into this path’s remaining components. The result is always relative.
Note reference_path is treated as a directory: every one of its trailing
components becomes a ... To build a markdown link relative to a note
file, use relative_link_from_note, which accounts for the note’s own
filename.
use kimun_core::nfs::VaultPath;
let from = VaultPath::new("/main/path/first");
let target = VaultPath::new("/main/second");
assert_eq!(target.get_relative_to(&from).to_string(), "../../second");Sourcepub fn from_path<P: AsRef<Path>, F: AsRef<Path>>(
workspace_path: P,
full_path: F,
) -> Result<Self, FSError>
pub fn from_path<P: AsRef<Path>, F: AsRef<Path>>( workspace_path: P, full_path: F, ) -> Result<Self, FSError>
Converts a real on-disk path back into an absolute vault path by
stripping the workspace_path prefix. Returns FSError::InvalidPath if
full_path does not live inside the workspace. Each OS component is run
through VaultPath::new, so the result is sanitized and lowercased.
Sourcepub fn is_note_file(&self) -> bool
pub fn is_note_file(&self) -> bool
Returns true if this path is a bare note filename: a single,
relative component ending in the note extension, with no directory part
(e.g. anton.md). Such paths are the signal for a vault-wide, wiki-style
name lookup rather than a directory-scoped path match.
use kimun_core::nfs::VaultPath;
assert!(VaultPath::new("anton.md").is_note_file());
assert!(!VaultPath::new("/work/anton.md").is_note_file());Sourcepub fn is_note(&self) -> bool
pub fn is_note(&self) -> bool
Returns true if this path points at a note, i.e. its final component
ends with the note extension. Unlike is_note_file, the path may have
any number of directory components.
Sourcepub fn ensure_note(&self) -> Result<(), FSError>
pub fn ensure_note(&self) -> Result<(), FSError>
Returns Ok if the path looks like a note path; otherwise an InvalidPath error.
Sourcepub fn ensure_directory(&self) -> Result<(), FSError>
pub fn ensure_directory(&self) -> Result<(), FSError>
Returns Ok if the path does not have a note extension; otherwise an InvalidPath error.
Sourcepub fn is_relative(&self) -> bool
pub fn is_relative(&self) -> bool
Returns true if this path is relative (not rooted at the vault root).
Sourcepub fn is_absolute(&self) -> bool
pub fn is_absolute(&self) -> bool
Returns true if this path is absolute (rooted at the vault root).
Sourcepub fn to_absolute(&mut self)
pub fn to_absolute(&mut self)
Marks this path absolute in place.
Sourcepub fn absolute(self) -> Self
pub fn absolute(self) -> Self
Consumes the path and returns it marked absolute (builder-style sibling
of to_absolute).
Sourcepub fn to_relative(&mut self)
pub fn to_relative(&mut self)
Marks this path relative in place.
Sourcepub fn get_parent_path(&self) -> (VaultPath, String)
pub fn get_parent_path(&self) -> (VaultPath, String)
Splits the path into its parent path and the final component’s name. The parent keeps this path’s absoluteness; the name is the empty string when the path has no components.
use kimun_core::nfs::VaultPath;
let (parent, name) = VaultPath::new("/a/b/c.md").get_parent_path();
assert_eq!(parent.to_string(), "/a/b");
assert_eq!(name, "c.md");Sourcepub fn append(&self, path: &VaultPath) -> VaultPath
pub fn append(&self, path: &VaultPath) -> VaultPath
Appends path to this one. If path is absolute it wins outright and is
returned as-is; otherwise its components are concatenated onto this path,
keeping this path’s absoluteness. The result is not flattened, so any
.. in path survives until flatten is called.
use kimun_core::nfs::VaultPath;
let base = VaultPath::new("/main/path");
let rel = VaultPath::new("sub/note.md");
assert_eq!(base.append(&rel).to_string(), "/main/path/sub/note.md");Trait Implementations§
Source§impl<'de> Deserialize<'de> for VaultPath
impl<'de> Deserialize<'de> for VaultPath
Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
impl Eq for VaultPath
Source§impl Ord for VaultPath
impl Ord for VaultPath
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialOrd for VaultPath
impl PartialOrd for VaultPath
impl StructuralPartialEq for VaultPath
Auto Trait Implementations§
impl Freeze for VaultPath
impl RefUnwindSafe for VaultPath
impl Send for VaultPath
impl Sync for VaultPath
impl Unpin for VaultPath
impl UnsafeUnpin for VaultPath
impl UnwindSafe for VaultPath
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more