pub struct SafePathSegment<'a>(/* private fields */);Expand description
A single URL path segment, checked at construction not to be exactly . or ...
A percent-encoded ./.. segment (. is an RFC 3986 unreserved character, so encoding
leaves it unchanged) still gets collapsed by a URL parser’s dot-segment normalization
(RFC 3986 §5.2.4) once interpolated into a request URL, letting it retarget the request
off the intended path prefix. A registry-fetch URL builder that takes SafePathSegment
instead of a raw &str/String cannot be called with an unchecked value — the dot-segment
guard is enforced by the type system rather than by caller convention.
Borrows rather than owns: every caller in this workspace validates a segment immediately
before building a URL from it and never stores the checked value, so an owned String
would only add an allocation. Copy for the same reason — passing it to more than one URL
builder (e.g. NuGet’s flat-container and registration-index URLs, built from the same
package name) needs no explicit .clone().
§Examples
use deps_core::path_segment::SafePathSegment;
assert!(SafePathSegment::new("left-pad").is_ok());
assert!(SafePathSegment::new(".").is_err());
assert!(SafePathSegment::new("..").is_err());Implementations§
Source§impl<'a> SafePathSegment<'a>
impl<'a> SafePathSegment<'a>
Sourcepub fn new(segment: &'a str) -> Result<Self, DotSegmentError<'a>>
pub fn new(segment: &'a str) -> Result<Self, DotSegmentError<'a>>
§Errors
Returns DotSegmentError if segment is exactly . or ...
Sourcepub fn checked_or_reject(
segment: &'a str,
name: &str,
context: &str,
registry: &'static str,
) -> Result<Self>
pub fn checked_or_reject( segment: &'a str, name: &str, context: &str, registry: &'static str, ) -> Result<Self>
Validates segment, converting a rejection directly into the registry-specific
DepsError::PackageNotFound via
dot_segment_rejection_error — the
single call every ecosystem crate’s own dot-segment gate (deps-composer, deps-dart,
deps-npm, deps-nuget) used to hand-roll separately as a SafePathSegment::new(...)
.map_err(...)pair (#1514 item 4 follow-up).
name is the full, possibly compound identifier surfaced in the resulting log/error —
not necessarily segment itself: a compound name (Composer’s vendor/package, npm’s
@scope/pkg) is split into more than one segment before each is checked here, and the
rejection should report the whole declared name a user recognizes, not just whichever
half happened to be the offending one.
§Errors
Returns DepsError::PackageNotFound if segment is exactly . or ...
§Examples
use deps_core::path_segment::SafePathSegment;
assert!(SafePathSegment::checked_or_reject("left-pad", "left-pad", "example URL", "npm").is_ok());
assert!(SafePathSegment::checked_or_reject("..", "@a/..", "example URL", "npm").is_err());Trait Implementations§
Source§impl<'a> Clone for SafePathSegment<'a>
impl<'a> Clone for SafePathSegment<'a>
impl<'a> Copy for SafePathSegment<'a>
Source§impl<'a> Debug for SafePathSegment<'a>
impl<'a> Debug for SafePathSegment<'a>
Source§impl Display for SafePathSegment<'_>
impl Display for SafePathSegment<'_>
impl<'a> Eq for SafePathSegment<'a>
Source§impl<'a> Hash for SafePathSegment<'a>
impl<'a> Hash for SafePathSegment<'a>
Source§impl<'a> PartialEq for SafePathSegment<'a>
impl<'a> PartialEq for SafePathSegment<'a>
impl<'a> StructuralPartialEq for SafePathSegment<'a>
Auto Trait Implementations§
impl<'a> Freeze for SafePathSegment<'a>
impl<'a> RefUnwindSafe for SafePathSegment<'a>
impl<'a> Send for SafePathSegment<'a>
impl<'a> Sync for SafePathSegment<'a>
impl<'a> Unpin for SafePathSegment<'a>
impl<'a> UnsafeUnpin for SafePathSegment<'a>
impl<'a> UnwindSafe for SafePathSegment<'a>
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<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.