pub struct VaultPath(/* private fields */);Expand description
A path inside a vault: root-relative, /-separated and normalized.
§Invariants
Every value of this type, however constructed, satisfies all of:
- it is either empty (the vault root itself) or a sequence of segments
joined by a single
/, with no leading or trailing/; - no segment is empty,
.or..; - no segment contains
/,\or NUL; - no segment is a bare drive designator (
C:), on any platform; - every segment is a single plain file-name component on the host
(
std::path::Component::Normal), soVaultPath::to_nativecan only ever produce a path under the root it is given.
Together these mean a VaultPath cannot name anything outside its vault
lexically. Symlinks are a separate question, answered where untrusted
input enters: super::Vault::canonicalize resolves them and reports
super::VaultError::OutsideRoot for a link that leaves the vault. Reads
do not re-check, for the reason the desktop scanner never has: it reads
every file in the repository, and a realpath per read would cost more than
the read.
§Separators
Parsing treats both / and \ as separators on every platform. A request
such as a\..\..\etc therefore normalizes (and is refused) identically on
Unix and Windows; the cost is that a Unix file whose name contains a
backslash is not addressable through a vault, which no portable repository
can contain anyway.
§Percent-encoding
None is decoded here. URL paths reach the resolver already decoded by axum,
and authored hrefs go through
crate::path_resolver::normalize_link_target first; decoding again would
turn a literal %2e%2e file name into a traversal.
Implementations§
Source§impl VaultPath
impl VaultPath
Sourcepub fn new(path: &str) -> Result<Self, VaultPathError>
pub fn new(path: &str) -> Result<Self, VaultPathError>
Parses a root-relative path, normalizing it lexically.
Accepts /- or \-separated input. . segments and repeated or
trailing separators are dropped; .. pops the previous segment and is
refused when there is nothing left to pop. A leading separator, a UNC
share or a drive designator is refused as VaultPathError::Absolute:
the callers of this function (request paths, repo-relative paths) are
relative by construction, so an absolute value is never a spelling of
something inside the vault.
Sourcepub fn from_relative_native(path: &Path) -> Result<Self, VaultPathError>
pub fn from_relative_native(path: &Path) -> Result<Self, VaultPathError>
Converts a repo-relative native path (such as
crate::repo::MarkdownInfo::raw_path) into a vault path.
. is dropped and .. pops, as in Self::new; a root or prefix
component, or a non-UTF-8 component, is refused.
Sourcepub fn from_absolute(root: &Path, path: &Path) -> Result<Self, VaultPathError>
pub fn from_absolute(root: &Path, path: &Path) -> Result<Self, VaultPathError>
Converts an absolute native path under root into a vault path.
Containment is component-wise (Path::strip_prefix), never textual,
and purely lexical: root and path must be spelled in the same base —
both canonical, in the vault’s case, which is what
super::LocalVault guarantees for the paths it produces.
Sourcepub fn segments(&self) -> impl Iterator<Item = &str>
pub fn segments(&self) -> impl Iterator<Item = &str>
The segments, outermost first. Empty for the root.
Sourcepub fn extension(&self) -> Option<&str>
pub fn extension(&self) -> Option<&str>
The final extension of Self::file_name, as Path::extension
defines it (archive.tar.gz → gz; .hidden → none).
Sourcepub fn ancestors(&self) -> impl Iterator<Item = Self>
pub fn ancestors(&self) -> impl Iterator<Item = Self>
This path and each ancestor, innermost first, ending at the root.
Sourcepub fn join(&self, relative: &str) -> Result<Self, VaultPathError>
pub fn join(&self, relative: &str) -> Result<Self, VaultPathError>
Appends a relative path (parsed with Self::new, so it may hold
several segments or ..). A .. may climb back out of self but never
past the vault root.
Sourcepub fn join_path(&self, other: &Self) -> Self
pub fn join_path(&self, other: &Self) -> Self
Appends another vault path. Infallible: both sides already satisfy the invariants, and concatenating valid segments cannot break them.
Sourcepub fn child(&self, name: &str) -> Result<Self, VaultPathError>
pub fn child(&self, name: &str) -> Result<Self, VaultPathError>
Appends exactly one segment — a directory entry’s own name. Unlike
Self::join, separators are refused rather than split on, so a Unix
file called a\b cannot become the two segments a/b.
Sourcepub fn starts_with(&self, prefix: &Self) -> bool
pub fn starts_with(&self, prefix: &Self) -> bool
Whether prefix is this path or one of its ancestors (segment-wise:
a/bc does not start with a/b).
Sourcepub fn to_native(&self, root: &Path) -> PathBuf
pub fn to_native(&self, root: &Path) -> PathBuf
The native path for this vault path under root.
Always root itself or a descendant of it: no segment can be a root, a
prefix or a .. (see the type’s invariants), so appending the segments
with the platform separator is exactly what pushing them one at a time
would produce — built in one allocation, because every index key and
every vault I/O goes through here.
Trait Implementations§
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,
1.21.0 (const: unstable) · Source§fn min(self, other: Self) -> Selfwhere
Self: Sized,
fn min(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> AsUncased for T
impl<T> AsUncased for T
Source§fn as_uncased(&self) -> &UncasedStr
fn as_uncased(&self) -> &UncasedStr
self to an UncasedStr.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
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 moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);