1use crate::languages::Language;
2use crate::uris::{ArchiveId, ArchiveURI, BaseURI, ModuleURI, Name, NameStep, SymbolURI};
3use std::ops::{BitAnd, BitOr, Div, Not, Rem};
4
5use super::name::{InvalidURICharacter, INVALID_CHARS};
6use super::{DocumentElementURI, DocumentURI, NarrativeURI, PathURI};
7
8impl<'a> Div<&'a str> for Name {
9 type Output = Result<Self,InvalidURICharacter>;
10 fn div(self, rhs: &'a str) -> Self::Output {
11 if rhs.contains(INVALID_CHARS) {
12 return Err(InvalidURICharacter);
13 }
14 let mut steps = self.0;
15 if rhs.contains('/') {
16 steps.extend(
17 rhs.split('/')
18 .map(|s| NameStep(crate::uris::name::NAMES.lock().get_or_intern(s))),
19 );
20 } else {
21 steps.push(NameStep(crate::uris::name::NAMES.lock().get_or_intern(rhs)));
22 }
23 Ok(Self(steps))
24 }
25}
26impl Div<String> for Name {
27 type Output = Result<Self,InvalidURICharacter>;
28 #[inline]
29 fn div(self, rhs: String) -> Self::Output {
30 self / rhs.as_str()
31 }
32}
33impl Div<NameStep> for Name {
34 type Output = Self;
35 #[inline]
36 fn div(mut self, rhs: NameStep) -> Self::Output {
37 self.0.push(rhs);
38 self
39 }
40}
41impl Div<Self> for Name {
42 type Output = Self;
43 #[inline]
44 fn div(mut self, rhs: Self) -> Self::Output {
45 self.0.extend(rhs.0);
46 self
47 }
48}
49
50impl BitAnd<ArchiveId> for BaseURI {
51 type Output = crate::uris::ArchiveURI;
52 #[inline]
53 fn bitand(self, rhs: ArchiveId) -> Self::Output {
54 crate::uris::ArchiveURI {
55 base: self,
56 archive: rhs,
57 }
58 }
59}
60impl BitAnd<&str> for BaseURI {
61 type Output = ArchiveURI;
62 #[inline]
63 fn bitand(self, rhs: &str) -> Self::Output {
64 <Self as BitAnd<ArchiveId>>::bitand(self, ArchiveId::new(rhs))
65 }
66}
67impl BitOr<Name> for ArchiveURI {
68 type Output = ModuleURI;
69 #[inline]
70 fn bitor(self, rhs: Name) -> Self::Output {
71 ModuleURI {
72 path: self.into(),
73 name: rhs
74 }
75 }
76}
77impl BitOr<&str> for ArchiveURI {
78 type Output = Result<ModuleURI,InvalidURICharacter>;
79 #[inline]
80 fn bitor(self, rhs: &str) -> Self::Output {
81 Ok(<Self as BitOr<Name>>::bitor(self, rhs.parse()?))
82 }
83}
84
85impl BitOr<Name> for ModuleURI {
86 type Output = SymbolURI;
87 #[inline]
88 fn bitor(self, rhs: Name) -> Self::Output {
89 SymbolURI {
90 module: self,
91 name: rhs,
92 }
93 }
94}
95impl BitOr<&str> for ModuleURI {
96 type Output = Result<SymbolURI,InvalidURICharacter>;
97 #[inline]
98 fn bitor(self, rhs: &str) -> Self::Output {
99 Ok(<Self as BitOr<Name>>::bitor(self, rhs.parse()?))
100 }
101}
102impl BitAnd<Name> for ArchiveURI {
103 type Output = DocumentURI;
104 #[inline]
105 fn bitand(self, rhs: Name) -> Self::Output {
106 DocumentURI {
107 path: self.into(),
108 name: rhs,
109 language: Language::default(),
110 }
111 }
112}
113impl BitAnd<&str> for ArchiveURI {
114 type Output = Result<DocumentURI,InvalidURICharacter>;
115 #[inline]
116 fn bitand(self, rhs: &str) -> Self::Output {
117 Ok(<Self as BitAnd<Name>>::bitand(self, rhs.parse()?))
118 }
119}
120
121impl Rem<Name> for ArchiveURI {
122 type Output = PathURI;
123 #[inline]
124 fn rem(self, rhs: Name) -> Self::Output {
125 PathURI {
126 archive: self,
127 path: Some(rhs),
128 }
129 }
130}
131
132impl Rem<&str> for ArchiveURI {
133 type Output = Result<PathURI,InvalidURICharacter>;
134 #[inline]
135 fn rem(self, rhs: &str) -> Self::Output {
136 Ok(PathURI {
137 archive: self,
138 path: if rhs.is_empty() {
139 None
140 } else {
141 Some(rhs.parse()?)
142 },
143 })
144 }
145}
146
147impl Div<Name> for PathURI {
148 type Output = Self;
149 fn div(self, rhs: Name) -> Self::Output {
150 Self {
151 archive: self.archive,
152 path: Some(if let Some(p) = self.path {
153 p / rhs
154 } else {rhs})
155 }
156 }
157}
158
159
160impl Div<&Name> for PathURI {
161 type Output = Self;
162 fn div(self, rhs: &Name) -> Self::Output {
163 self / rhs.clone()
164 }
165}
166
167impl Div<&str> for PathURI {
168 type Output = Result<Self,InvalidURICharacter>;
169 fn div(self, rhs: &str) -> Self::Output {
170 if rhs.is_empty() {
171 Ok(self)
172 } else {
173 Ok(self / rhs.parse::<Name>()?)
174 }
175 }
176}
177
178impl BitOr<Name> for PathURI {
179 type Output = ModuleURI;
180 #[inline]
181 fn bitor(self, rhs: Name) -> Self::Output {
182 ModuleURI {
183 path: self,
184 name: rhs
185 }
186 }
187}
188impl BitOr<&str> for PathURI {
189 type Output = Result<ModuleURI,InvalidURICharacter>;
190 #[inline]
191 fn bitor(self, rhs: &str) -> Self::Output {
192 Ok(<Self as BitOr<Name>>::bitor(self, rhs.parse()?))
193 }
194}
195
196impl BitAnd<(Name, Language)> for ArchiveURI {
197 type Output = DocumentURI;
198 #[inline]
199 fn bitand(self, rhs: (Name, Language)) -> Self::Output {
200 DocumentURI {
201 path: self.into(),
202 name: rhs.0,
203 language: rhs.1,
204 }
205 }
206}
207impl BitAnd<(&str, Language)> for ArchiveURI {
208 type Output = Result<DocumentURI,InvalidURICharacter>;
209 #[inline]
210 fn bitand(self, rhs: (&str, Language)) -> Self::Output {
211 Ok(<Self as BitAnd<(Name, Language)>>::bitand(self, (rhs.0.parse()?, rhs.1)))
212 }
213}
214impl BitAnd<(Name, Language)> for PathURI {
215 type Output = DocumentURI;
216 #[inline]
217 fn bitand(self, rhs: (Name, Language)) -> Self::Output {
218 DocumentURI {
219 path: self,
220 name: rhs.0,
221 language: rhs.1,
222 }
223 }
224}
225impl BitAnd<(&str, Language)> for PathURI {
226 type Output = Result<DocumentURI,InvalidURICharacter>;
227 #[inline]
228 fn bitand(self, rhs: (&str, Language)) -> Self::Output {
229 Ok(<Self as BitAnd<(Name, Language)>>::bitand(self, (rhs.0.parse()?, rhs.1)))
230 }
231}
232
233#[allow(clippy::suspicious_arithmetic_impl)]
234impl BitAnd<Name> for NarrativeURI {
235 type Output = DocumentElementURI;
236 #[inline]
237 fn bitand(self,rhs:Name) -> Self::Output {
238 match self {
239 Self::Document(d) => DocumentElementURI {
240 document: d,
241 name: rhs
242 },
243 Self::Element(e) => e / rhs
244 }
245 }
246}
247impl BitAnd<&str> for NarrativeURI {
248 type Output = Result<DocumentElementURI,InvalidURICharacter>;
249 #[inline]
250 fn bitand(self,rhs:&str) -> Self::Output {
251 Ok(self & rhs.parse::<Name>()?)
252 }
253}
254
255#[allow(clippy::suspicious_arithmetic_impl)]
256impl BitAnd<Name> for DocumentURI {
257 type Output = DocumentElementURI;
258 #[inline]
259 fn bitand(self,rhs:Name) -> Self::Output {
260 DocumentElementURI {
261 document: self,
262 name: rhs
263 }
264 }
265}
266impl BitAnd<&str> for DocumentURI {
267 type Output = Result<DocumentElementURI,InvalidURICharacter>;
268 #[inline]
269 fn bitand(self,rhs:&str) -> Self::Output {
270 Ok(self & rhs.parse::<Name>()?)
271 }
272}
273
274impl Not for ModuleURI {
275 type Output = Self;
276 #[inline]
277 fn not(self) -> Self::Output {
278 if self.name.is_simple() {
279 return self;
280 }
281 let name = self.name.steps().first().unwrap_or_else(|| unreachable!());
282 let name = name.clone().into();
283 Self {
284 path: self.path,
285 name,
286 }
287 }
288}
289
290
291impl<'a> Div<&'a str> for ModuleURI {
292 type Output = Result<Self,InvalidURICharacter>;
293 fn div(self, rhs: &'a str) -> Self::Output {
294 Ok(Self {
295 path:self.path,
296 name:self.name / rhs.parse::<Name>()?
297 })
298 }
299}
300impl Div<String> for ModuleURI {
301 type Output = Result<Self,InvalidURICharacter>;
302 #[inline]
303 fn div(self, rhs: String) -> Self::Output {
304 self / rhs.as_str()
305 }
306}
307impl Div<NameStep> for ModuleURI {
308 type Output = Self;
309 #[inline]
310 fn div(mut self, rhs: NameStep) -> Self::Output {
311 self.name.0.push(rhs);
312 self
313 }
314}
315impl Div<Name> for ModuleURI {
316 type Output = Self;
317 #[inline]
318 fn div(mut self, rhs: Name) -> Self::Output {
319 self.name.0.extend(rhs.0);
320 self
321 }
322}
323
324
325impl<'a> Div<&'a str> for DocumentElementURI {
326 type Output = Result<Self,InvalidURICharacter>;
327 fn div(self, rhs: &'a str) -> Self::Output {
328 Ok(Self {
329 document:self.document,
330 name:(self.name / rhs)?
331 })
332 }
333}
334impl Div<String> for DocumentElementURI {
335 type Output = Result<Self,InvalidURICharacter>;
336 #[inline]
337 fn div(self, rhs: String) -> Self::Output {
338 self / rhs.as_str()
339 }
340}
341impl Div<NameStep> for DocumentElementURI {
342 type Output = Self;
343 #[inline]
344 fn div(mut self, rhs: NameStep) -> Self::Output {
345 self.name.0.push(rhs);
346 self
347 }
348}
349impl Div<Name> for DocumentElementURI {
350 type Output = Self;
351 #[inline]
352 fn div(mut self, rhs: Name) -> Self::Output {
353 self.name.0.extend(rhs.0);
354 self
355 }
356}