pub struct SafeRelativePathBuf(/* private fields */);Expand description
An owned relative path that statically cannot escape its parent.
SafeRelativePathBuf is to SafeRelativePath what PathBuf is to
Path in the standard library: same guarantee, same string form,
owned instead of borrowed. Construct one by parsing a string with
str::parse (or from_relative_path),
or deserialise one from anywhere serde reaches.
All methods on SafeRelativePath are reachable through Deref, so
try_join, to_full_path, safe_parent, and friends are all in scope
without an explicit reborrow.
§Example
use zenops_safe_relative_path::SafeRelativePathBuf;
let p: SafeRelativePathBuf = "configs/app.toml".parse().unwrap();
assert_eq!(p.as_str(), "configs/app.toml");
assert_eq!(p.safe_parent().unwrap().as_str(), "configs");Implementations§
Source§impl SafeRelativePathBuf
impl SafeRelativePathBuf
Sourcepub fn from_relative_path<P>(v: &P) -> Result<Self, Error>
pub fn from_relative_path<P>(v: &P) -> Result<Self, Error>
Parse and validate an arbitrary path into a SafeRelativePathBuf.
Same contract as SafeRelativePath::from_relative_path — rejects
any path containing .. — but returns an owned buffer. Most callers
can reach for str::parse instead, which forwards here.
Methods from Deref<Target = SafeRelativePath>§
Sourcepub fn to_safe_relative_path_buf(&self) -> SafeRelativePathBuf
pub fn to_safe_relative_path_buf(&self) -> SafeRelativePathBuf
Copy this borrowed path into an owned SafeRelativePathBuf.
Sourcepub fn normalize_safe(&self) -> SafeRelativePathBuf
pub fn normalize_safe(&self) -> SafeRelativePathBuf
Collapse . components and produce a normalised owned path.
Unlike Path::canonicalize this is purely lexical — no filesystem
access. A SafeRelativePath cannot contain .. segments, so
normalisation only ever drops . components.
§Example
use zenops_safe_relative_path::SafeRelativePath;
let p = SafeRelativePath::from_relative_path("a/./b").unwrap();
assert_eq!(p.normalize_safe().as_str(), "a/b");Sourcepub fn safe_join(
&self,
path: impl AsRef<SafeRelativePath>,
) -> SafeRelativePathBuf
pub fn safe_join( &self, path: impl AsRef<SafeRelativePath>, ) -> SafeRelativePathBuf
Join another already-safe path onto this one.
The infallible counterpart to try_join: both
sides are already known to be safe, so the join cannot introduce
traversal and no validation is needed.
§Example
use zenops_safe_relative_path::srpath;
let joined = srpath!("config").safe_join(srpath!("app.toml"));
assert_eq!(joined.as_str(), "config/app.toml");Sourcepub fn try_join(
&self,
path: impl AsRef<RelativePath>,
) -> Result<SafeRelativePathBuf, Error>
pub fn try_join( &self, path: impl AsRef<RelativePath>, ) -> Result<SafeRelativePathBuf, Error>
Join another path onto this one, returning an error if the joined segment would escape.
This is the safe counterpart to Path::join for inputs that come
from configuration or another untrusted source: the result is still
a relative path contained by the original base.
§Example
use zenops_safe_relative_path::srpath;
let base = srpath!("config");
assert_eq!(
base.try_join("app.toml").unwrap().as_str(),
"config/app.toml",
);
assert!(base.try_join("../../etc/passwd").is_err());Sourcepub fn to_full_path(&self, base: impl AsRef<Path>) -> PathBuf
pub fn to_full_path(&self, base: impl AsRef<Path>) -> PathBuf
Resolve this relative path against base to produce an absolute
PathBuf.
Use this at the edge of the program, when a SafeRelativePath
finally needs to be handed to a filesystem call against a known
root — typically $HOME or $XDG_CONFIG_HOME. The result is base
followed by this path’s components, with no .. traversal between
them.
§Example
use std::path::Path;
use zenops_safe_relative_path::srpath;
let abs = srpath!("config/app.toml").to_full_path(Path::new("/home/ada"));
assert_eq!(abs, Path::new("/home/ada/config/app.toml"));Sourcepub fn safe_parent(&self) -> Option<&SafeRelativePath>
pub fn safe_parent(&self) -> Option<&SafeRelativePath>
Return the parent path, or None if there is no parent.
The parent of a SafeRelativePath is itself a SafeRelativePath
— dropping a final component can never introduce traversal.
§Example
use zenops_safe_relative_path::srpath;
assert_eq!(srpath!("a/b/c").safe_parent().unwrap().as_str(), "a/b");
assert!(srpath!("").safe_parent().is_none());Trait Implementations§
Source§impl AsRef<OsStr> for SafeRelativePathBuf
impl AsRef<OsStr> for SafeRelativePathBuf
Source§impl AsRef<RelativePath> for SafeRelativePathBuf
impl AsRef<RelativePath> for SafeRelativePathBuf
Source§fn as_ref(&self) -> &RelativePath
fn as_ref(&self) -> &RelativePath
Source§impl AsRef<SafeRelativePath> for SafeRelativePathBuf
impl AsRef<SafeRelativePath> for SafeRelativePathBuf
Source§fn as_ref(&self) -> &SafeRelativePath
fn as_ref(&self) -> &SafeRelativePath
Source§impl Clone for SafeRelativePathBuf
impl Clone for SafeRelativePathBuf
Source§fn clone(&self) -> SafeRelativePathBuf
fn clone(&self) -> SafeRelativePathBuf
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more