iref_core/uri/path/
segment.rs

1use pct_str::PctStr;
2use std::{
3	cmp,
4	hash::{self, Hash},
5	ops,
6};
7
8use static_regular_grammar::RegularGrammar;
9
10use crate::common::path::SegmentImpl;
11
12/// IRI path segment.
13#[derive(RegularGrammar)]
14#[grammar(
15	file = "src/uri/grammar.abnf",
16	entry_point = "segment",
17	name = "URI path segment",
18	ascii,
19	no_deref,
20	cache = "automata/uri/segment.aut.cbor"
21)]
22#[grammar(sized(
23	SegmentBuf,
24	derive(Debug, Display, PartialEq, Eq, PartialOrd, Ord, Hash)
25))]
26#[cfg_attr(feature = "serde", grammar(serde))]
27#[cfg_attr(feature = "ignore-grammars", grammar(disable))]
28pub struct Segment([u8]);
29
30impl SegmentImpl for Segment {
31	const PARENT: &'static Self = Self::PARENT;
32
33	const EMPTY: &'static Self = Self::EMPTY;
34
35	unsafe fn new_unchecked(bytes: &[u8]) -> &Self {
36		Self::new_unchecked(bytes)
37	}
38
39	fn as_bytes(&self) -> &[u8] {
40		&self.0
41	}
42}
43
44impl Segment {
45	pub const CURRENT: &'static Self = unsafe { Segment::new_unchecked(b".") };
46
47	pub const PARENT: &'static Self = unsafe { Segment::new_unchecked(b"..") };
48
49	/// Returns the segment as a percent-encoded string slice.
50	#[inline]
51	pub fn as_pct_str(&self) -> &PctStr {
52		SegmentImpl::as_pct_str(self)
53	}
54
55	/// Checks if this segments looks like a scheme part.
56	///
57	/// Returns `true` is of the form `prefix:suffix` where `prefix` is a valid
58	/// scheme, of `false` otherwise.
59	#[inline]
60	pub fn looks_like_scheme(&self) -> bool {
61		SegmentImpl::looks_like_scheme(self)
62	}
63}
64
65impl ops::Deref for Segment {
66	type Target = PctStr;
67
68	fn deref(&self) -> &Self::Target {
69		self.as_pct_str()
70	}
71}
72
73impl PartialEq for Segment {
74	fn eq(&self, other: &Self) -> bool {
75		self.as_pct_str() == other.as_pct_str()
76	}
77}
78
79impl Eq for Segment {}
80
81impl PartialOrd for Segment {
82	fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
83		Some(self.cmp(other))
84	}
85}
86
87impl Ord for Segment {
88	fn cmp(&self, other: &Self) -> cmp::Ordering {
89		self.as_pct_str().cmp(other.as_pct_str())
90	}
91}
92
93impl Hash for Segment {
94	fn hash<H: hash::Hasher>(&self, state: &mut H) {
95		self.as_pct_str().hash(state)
96	}
97}