diff --git a/crates/nu-path/src/form.rs b/crates/nu-path/src/form.rs index 2012d1b9da..3eef263f8a 100644 --- a/crates/nu-path/src/form.rs +++ b/crates/nu-path/src/form.rs @@ -117,15 +117,15 @@ impl PathJoin for Canonical { type Output = Absolute; } -/// A marker trait for [`PathForm`]s that support mutation. +/// A marker trait for [`PathForm`]s that support setting the file name or extension. /// /// This includes the [`Any`], [`Relative`], and [`Absolute`] path forms. -/// [`Canonical`] paths do not support mutation, -/// since unguarded mutation can cause them to no longer be canonical. -pub trait PathMut: PathForm {} -impl PathMut for Any {} -impl PathMut for Relative {} -impl PathMut for Absolute {} +/// [`Canonical`] paths do not support this, since appending file names and extensions that contain +/// path separators can cause the path to no longer be canonical. +pub trait PathSet: PathForm {} +impl PathSet for Any {} +impl PathSet for Relative {} +impl PathSet for Absolute {} /// A marker trait for [`PathForm`]s that support pushing [`MaybeRelative`] paths. /// @@ -134,6 +134,6 @@ impl PathMut for Absolute {} /// which is why they do not support pushing. /// In the future, a `push_rel` and/or a `try_push` method could be added as an alternative. /// Similarly, [`Canonical`] paths may become uncanonical if a non-canonical path is pushed onto it. -pub trait PathPush: PathMut {} +pub trait PathPush: PathSet {} impl PathPush for Any {} impl PathPush for Absolute {} diff --git a/crates/nu-path/src/path.rs b/crates/nu-path/src/path.rs index 8ca1a6792a..38e9270e40 100644 --- a/crates/nu-path/src/path.rs +++ b/crates/nu-path/src/path.rs @@ -1,6 +1,6 @@ use crate::form::{ Absolute, Any, Canonical, IsAbsolute, MaybeAbsolute, MaybeRelative, PathCast, PathForm, - PathJoin, PathMut, PathPush, Relative, + PathJoin, PathPush, PathSet, Relative, }; use std::{ borrow::{Borrow, Cow}, @@ -198,6 +198,11 @@ impl Path { Self::new_unchecked(path) } + #[inline] + pub fn as_mut_os_str(&mut self) -> &mut OsStr { + self.inner.as_mut_os_str() + } + #[inline] pub fn is_absolute(&self) -> bool { self.inner.is_absolute() @@ -230,12 +235,7 @@ impl Path
{ } } -impl Path { - #[inline] - pub fn as_mut_os_str(&mut self) -> &mut OsStr { - self.inner.as_mut_os_str() - } - +impl Path { #[inline] pub fn with_file_name(&self, file_name: impl AsRef) -> PathBuf { PathBuf::new_unchecked(self.inner.with_file_name(file_name)) @@ -486,6 +486,11 @@ impl PathBuf { Self::new_unchecked(std::path::PathBuf::with_capacity(capacity)) } + #[inline] + pub fn as_mut_os_string(&mut self) -> &mut OsString { + self.inner.as_mut_os_string() + } + #[inline] pub fn clear(&mut self) { self.inner.clear() @@ -517,12 +522,7 @@ impl PathBuf { } } -impl PathBuf { - #[inline] - pub fn as_mut_os_string(&mut self) -> &mut OsString { - self.inner.as_mut_os_string() - } - +impl PathBuf { #[inline] pub fn set_file_name(&mut self, file_name: impl AsRef) { self.inner.set_file_name(file_name) @@ -587,12 +587,12 @@ impl Deref for PathBuf { } } -impl DerefMut for PathBuf { +impl DerefMut for PathBuf { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { // Safety: `Path` is a repr(transparent) wrapper around `std::path::Path`. let path: &mut std::path::Path = &mut self.inner; - let ptr = std::ptr::from_mut(path) as *mut Path; + let ptr = std::ptr::from_mut(path) as *mut Path; unsafe { &mut *ptr } } }