flams_ontology/uris/narrative/
mod.rs

1use crate::languages::Language;
2use crate::uris::narrative::document_elements::DocumentElementURI;
3use crate::uris::narrative::documents::DocumentURI;
4use crate::uris::{
5    debugdisplay, ArchiveURIRef, ArchiveURITrait, BaseURI, ContentURI, ContentURIRef,
6    ContentURITrait, ModuleURI, PathURITrait, SymbolURI, URIOrRefTrait, URIParseError, URIRef,
7    URIRefTrait, URITrait, URIWithLanguage,
8};
9use const_format::concatcp;
10use std::fmt::Display;
11use std::str::FromStr;
12
13pub(super) mod document_elements;
14pub(super) mod documents;
15
16pub trait NarrativeURITrait: URIWithLanguage {
17    fn as_narrative(&self) -> NarrativeURIRef;
18    fn document(&self) -> &DocumentURI;
19}
20
21#[derive(Clone, Hash, PartialEq, Eq)]
22pub enum NarrativeURI {
23    Document(DocumentURI),
24    Element(DocumentElementURI),
25}
26impl From<DocumentURI> for NarrativeURI {
27    #[inline]
28    fn from(value: DocumentURI) -> Self {
29        Self::Document(value)
30    }
31}
32impl From<DocumentElementURI> for NarrativeURI {
33    #[inline]
34    fn from(value: DocumentElementURI) -> Self {
35        Self::Element(value)
36    }
37}
38impl URIOrRefTrait for NarrativeURI {
39    #[inline]
40    fn base(&self) -> &BaseURI {
41        match self {
42            Self::Document(m) => m.base(),
43            Self::Element(s) => s.base(),
44        }
45    }
46    #[inline]
47    fn as_uri(&self) -> URIRef {
48        URIRef::Narrative(self.as_narrative())
49    }
50}
51impl URITrait for NarrativeURI {
52    type Ref<'a> = NarrativeURIRef<'a>;
53}
54impl URIWithLanguage for NarrativeURI {
55    #[inline]
56    fn language(&self) -> Language {
57        match self {
58            Self::Document(m) => m.language,
59            Self::Element(s) => s.language(),
60        }
61    }
62}
63impl NarrativeURITrait for NarrativeURI {
64    #[inline]
65    fn as_narrative(&self) -> NarrativeURIRef {
66        match self {
67            Self::Document(m) => NarrativeURIRef::Document(m),
68            Self::Element(s) => NarrativeURIRef::Element(s),
69        }
70    }
71    #[inline]
72    fn document(&self) -> &DocumentURI {
73        match self {
74            Self::Document(m) => m,
75            Self::Element(s) => s.document(),
76        }
77    }
78}
79
80#[derive(Clone, Copy, Hash, PartialEq, Eq)]
81pub enum NarrativeURIRef<'a> {
82    Document(&'a DocumentURI),
83    Element(&'a DocumentElementURI),
84}
85
86impl URIWithLanguage for NarrativeURIRef<'_> {
87    #[inline]
88    fn language(&self) -> Language {
89        match self {
90            Self::Document(m) => m.language,
91            Self::Element(s) => s.language(),
92        }
93    }
94}
95impl<'a> From<&'a NarrativeURI> for NarrativeURIRef<'a> {
96    #[inline]
97    fn from(value: &'a NarrativeURI) -> Self {
98        match value {
99            NarrativeURI::Document(m) => Self::Document(m),
100            NarrativeURI::Element(s) => Self::Element(s),
101        }
102    }
103}
104impl URIOrRefTrait for NarrativeURIRef<'_> {
105    #[inline]
106    fn base(&self) -> &BaseURI {
107        match self {
108            Self::Document(m) => m.base(),
109            Self::Element(s) => s.base(),
110        }
111    }
112    #[inline]
113    fn as_uri(&self) -> URIRef {
114        URIRef::Narrative(self.as_narrative())
115    }
116}
117
118impl<'a> URIRefTrait<'a> for NarrativeURIRef<'a> {
119    type Owned = NarrativeURI;
120    #[inline]
121    fn owned(self) -> NarrativeURI {
122        match self {
123            Self::Document(m) => NarrativeURI::Document(m.clone()),
124            Self::Element(s) => NarrativeURI::Element(s.clone()),
125        }
126    }
127}
128impl NarrativeURITrait for NarrativeURIRef<'_> {
129    #[inline]
130    fn as_narrative(&self) -> NarrativeURIRef {
131        *self
132    }
133    #[inline]
134    fn document(&self) -> &DocumentURI {
135        match self {
136            Self::Document(m) => m,
137            Self::Element(s) => s.document(),
138        }
139    }
140}
141impl Display for NarrativeURI {
142    #[inline]
143    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144        match self {
145            Self::Document(m) => Display::fmt(m, f),
146            Self::Element(s) => Display::fmt(s, f),
147        }
148    }
149}
150debugdisplay!(NarrativeURI);
151impl Display for NarrativeURIRef<'_> {
152    #[inline]
153    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
154        match self {
155            Self::Document(m) => Display::fmt(m, f),
156            Self::Element(s) => Display::fmt(s, f),
157        }
158    }
159}
160debugdisplay!(NarrativeURIRef<'_>);
161
162impl ArchiveURITrait for NarrativeURI {
163    #[inline]
164    fn archive_uri(&self) -> ArchiveURIRef {
165        self.document().archive_uri()
166    }
167}
168impl ArchiveURITrait for NarrativeURIRef<'_> {
169    #[inline]
170    fn archive_uri(&self) -> ArchiveURIRef {
171        self.document().archive_uri()
172    }
173}
174
175impl PathURITrait for NarrativeURI {
176    #[inline]
177    fn as_path(&self) -> crate::uris::PathURIRef {
178        self.document().as_path()
179    }
180    #[inline]
181    fn path(&self) -> Option<&crate::uris::Name> {
182        self.document().path()
183    }
184}
185impl PathURITrait for NarrativeURIRef<'_> {
186    #[inline]
187    fn as_path(&self) -> crate::uris::PathURIRef {
188        self.document().as_path()
189    }
190    #[inline]
191    fn path(&self) -> Option<&crate::uris::Name> {
192        self.document().path()
193    }
194}
195
196impl FromStr for NarrativeURI {
197    type Err = URIParseError;
198    fn from_str(s: &str) -> Result<Self, Self::Err> {
199        DocumentURI::pre_parse(s, "narrative uri", |document, mut split| {
200            let Some(c) = split.next() else {
201                return Ok(Self::Document(document));
202            };
203            c.strip_prefix(concatcp!(DocumentElementURI::SEPARATOR, "="))
204                .map_or_else(
205                    || {
206                        Err(URIParseError::TooManyPartsFor {
207                            uri_kind: "narrative uri",
208                            original: s.to_string(),
209                        })
210                    },
211                    |name| {
212                        Ok(Self::Element(DocumentElementURI {
213                            document,
214                            name: name.parse()?,
215                        }))
216                    },
217                )
218        })
219    }
220}
221
222#[cfg(feature = "serde")]
223mod serde_impl {
224    use crate::uris::{serialize, NarrativeURI, NarrativeURIRef};
225    serialize!(DE NarrativeURI);
226    serialize!(NarrativeURIRef<'_>);
227}