flams_ontology/uris/
infix.rs

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}