Add debug asserts
This commit is contained in:
parent
f0be6ddc08
commit
670f77be9b
|
@ -1,10 +1,16 @@
|
|||
use std::ffi::OsStr;
|
||||
|
||||
mod private {
|
||||
use std::ffi::OsStr;
|
||||
|
||||
// This trait should not be extended by external crates in order to uphold safety guarantees.
|
||||
// As such, this trait is put inside a private module to prevent external impls.
|
||||
// This ensures that all possible [`PathForm`]s can only be defined here and will:
|
||||
// - be zero sized (enforced anyways by the `repr(transparent)` on `Path`)
|
||||
// - have a no-op [`Drop`] implementation
|
||||
pub trait Sealed {}
|
||||
pub trait Sealed {
|
||||
fn invariants_satisfied<P: AsRef<OsStr> + ?Sized>(path: &P) -> bool;
|
||||
}
|
||||
}
|
||||
|
||||
/// A marker trait for the different kinds of path forms.
|
||||
|
@ -26,7 +32,11 @@ impl PathForm for Canonical {}
|
|||
/// trailing slashes, dot components (`..` or `.`), and repeated path separators.
|
||||
pub struct Any;
|
||||
|
||||
impl private::Sealed for Any {}
|
||||
impl private::Sealed for Any {
|
||||
fn invariants_satisfied<P: AsRef<OsStr> + ?Sized>(_: &P) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// A strictly relative path.
|
||||
///
|
||||
|
@ -34,7 +44,11 @@ impl private::Sealed for Any {}
|
|||
/// trailing slashes, dot components (`..` or `.`), and repeated path separators.
|
||||
pub struct Relative;
|
||||
|
||||
impl private::Sealed for Relative {}
|
||||
impl private::Sealed for Relative {
|
||||
fn invariants_satisfied<P: AsRef<OsStr> + ?Sized>(path: &P) -> bool {
|
||||
std::path::Path::new(path).is_relative()
|
||||
}
|
||||
}
|
||||
|
||||
/// An absolute path.
|
||||
///
|
||||
|
@ -42,14 +56,22 @@ impl private::Sealed for Relative {}
|
|||
/// trailing slashes, dot components (`..` or `.`), and repeated path separators.
|
||||
pub struct Absolute;
|
||||
|
||||
impl private::Sealed for Absolute {}
|
||||
impl private::Sealed for Absolute {
|
||||
fn invariants_satisfied<P: AsRef<OsStr> + ?Sized>(path: &P) -> bool {
|
||||
std::path::Path::new(path).is_absolute()
|
||||
}
|
||||
}
|
||||
|
||||
// A canonical path.
|
||||
//
|
||||
// An absolute path with all intermediate components normalized and symbolic links resolved.
|
||||
pub struct Canonical;
|
||||
|
||||
impl private::Sealed for Canonical {}
|
||||
impl private::Sealed for Canonical {
|
||||
fn invariants_satisfied<P: AsRef<OsStr> + ?Sized>(_: &P) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// A marker trait for [`PathForm`]s that may be relative paths.
|
||||
/// This includes only the [`Any`] and [`Relative`] path forms.
|
||||
|
|
|
@ -161,6 +161,7 @@ impl<Form: PathForm> Path<Form> {
|
|||
/// Create a new path of any form without validating invariants.
|
||||
#[inline]
|
||||
fn new_unchecked<P: AsRef<OsStr> + ?Sized>(path: &P) -> &Self {
|
||||
debug_assert!(Form::invariants_satisfied(path));
|
||||
// Safety: `Path<Form>` is a repr(transparent) wrapper around `std::path::Path`.
|
||||
let path = std::path::Path::new(path.as_ref());
|
||||
let ptr = std::ptr::from_ref(path) as *const Self;
|
||||
|
@ -705,9 +706,11 @@ impl Path {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn try_absolute(&self) -> Result<&AbsolutePath, &RelativePath> {
|
||||
self.is_absolute()
|
||||
.then_some(AbsolutePath::new_unchecked(&self.inner))
|
||||
.ok_or(RelativePath::new_unchecked(&self.inner))
|
||||
if self.is_absolute() {
|
||||
Ok(AbsolutePath::new_unchecked(&self.inner))
|
||||
} else {
|
||||
Err(RelativePath::new_unchecked(&self.inner))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an `Ok` [`RelativePath`] if the [`Path`] is relative.
|
||||
|
@ -722,9 +725,11 @@ impl Path {
|
|||
/// ```
|
||||
#[inline]
|
||||
pub fn try_relative(&self) -> Result<&RelativePath, &AbsolutePath> {
|
||||
self.is_relative()
|
||||
.then_some(RelativePath::new_unchecked(&self.inner))
|
||||
.ok_or(AbsolutePath::new_unchecked(&self.inner))
|
||||
if self.is_relative() {
|
||||
Ok(RelativePath::new_unchecked(&self.inner))
|
||||
} else {
|
||||
Err(AbsolutePath::new_unchecked(&self.inner))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1372,6 +1377,7 @@ impl<Form: PathForm> PathBuf<Form> {
|
|||
/// Create a new [`PathBuf`] of any form without validiting invariants.
|
||||
#[inline]
|
||||
pub(crate) fn new_unchecked(buf: std::path::PathBuf) -> Self {
|
||||
debug_assert!(Form::invariants_satisfied(&buf));
|
||||
Self {
|
||||
_form: PhantomData,
|
||||
inner: buf,
|
||||
|
|
Loading…
Reference in New Issue
Block a user