iref_core/uri/
authority.rs

1use std::{
2	cmp,
3	hash::{self, Hash},
4};
5
6use static_regular_grammar::RegularGrammar;
7
8mod host;
9mod port;
10mod userinfo;
11
12use crate::common::AuthorityImpl;
13
14pub use host::*;
15pub use port::*;
16pub use userinfo::*;
17
18#[derive(RegularGrammar)]
19#[grammar(
20	file = "src/uri/grammar.abnf",
21	entry_point = "authority",
22	name = "URI authority",
23	ascii,
24	cache = "automata/uri/authority.aut.cbor"
25)]
26#[grammar(sized(
27	AuthorityBuf,
28	derive(Debug, Display, PartialEq, Eq, PartialOrd, Ord, Hash)
29))]
30#[cfg_attr(feature = "serde", grammar(serde))]
31#[cfg_attr(feature = "ignore-grammars", grammar(disable))]
32pub struct Authority([u8]);
33
34impl AuthorityImpl for Authority {
35	type UserInfo = UserInfo;
36	type Host = Host;
37
38	unsafe fn new_unchecked(bytes: &[u8]) -> &Self {
39		Self::new_unchecked(bytes)
40	}
41
42	fn as_bytes(&self) -> &[u8] {
43		&self.0
44	}
45}
46
47#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
48pub struct AuthorityParts<'a> {
49	pub user_info: Option<&'a UserInfo>,
50	pub host: &'a Host,
51	pub port: Option<&'a Port>,
52}
53
54impl Authority {
55	pub fn user_info(&self) -> Option<&UserInfo> {
56		AuthorityImpl::user_info(self)
57	}
58
59	pub fn host(&self) -> &Host {
60		AuthorityImpl::host(self)
61	}
62
63	pub fn port(&self) -> Option<&Port> {
64		AuthorityImpl::port(self)
65	}
66
67	pub fn parts(&self) -> AuthorityParts {
68		let ranges = AuthorityImpl::parts(self);
69
70		AuthorityParts {
71			user_info: ranges
72				.user_info
73				.map(|r| unsafe { UserInfo::new_unchecked(&self.0[r]) }),
74			host: unsafe { Host::new_unchecked(&self.0[ranges.host]) },
75			port: ranges
76				.port
77				.map(|r| unsafe { Port::new_unchecked(&self.0[r]) }),
78		}
79	}
80}
81
82impl cmp::PartialEq for Authority {
83	#[inline]
84	fn eq(&self, other: &Authority) -> bool {
85		self.parts() == other.parts()
86	}
87}
88
89impl Eq for Authority {}
90
91impl<'a> PartialEq<&'a str> for Authority {
92	#[inline]
93	fn eq(&self, other: &&'a str) -> bool {
94		self.as_str() == *other
95	}
96}
97
98impl PartialOrd for Authority {
99	#[inline]
100	fn partial_cmp(&self, other: &Authority) -> Option<cmp::Ordering> {
101		Some(self.cmp(other))
102	}
103}
104
105impl Ord for Authority {
106	#[inline]
107	fn cmp(&self, other: &Authority) -> cmp::Ordering {
108		self.parts().cmp(&other.parts())
109	}
110}
111
112impl Hash for Authority {
113	#[inline]
114	fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
115		self.parts().hash(hasher)
116	}
117}