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