flams_ontology/uris/content/
modules.rs

1use crate::languages::Language;
2use crate::uris::errors::URIParseError;
3use crate::uris::macros::debugdisplay;
4use crate::uris::{
5    ArchiveURI, ArchiveURIRef, ArchiveURITrait, BaseURI, ContentURIRef, ContentURITrait, Name,
6    PathURI, PathURIRef, PathURITrait, SymbolURI, URIOrRefTrait, URIRef, URIRefTrait, URITrait,
7    URIWithLanguage, URI,
8};
9use const_format::concatcp;
10use std::fmt::Display;
11use std::str::{FromStr, Split};
12
13use super::ContentURI;
14
15#[cfg(feature = "wasm")]
16#[cfg_attr(
17    feature = "wasm",
18    wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)
19)]
20const TS_URI: &str = "export type ModuleURI = string;";
21
22#[derive(Clone, PartialEq, Eq, Hash)]
23pub struct ModuleURI {
24    pub(in crate::uris) path: PathURI,
25    pub(in crate::uris) name: Name,
26}
27
28impl ModuleURI {
29    pub const SEPARATOR: char = 'm';
30    #[must_use]
31    pub fn into_symbol(mut self) -> Option<SymbolURI> {
32        let last = self.name.0.pop()?;
33        if self.name.0.is_empty() {
34            return None;
35        }
36        Some(SymbolURI {
37            module: self,
38            name: last.into(),
39        })
40    }
41}
42impl Display for ModuleURI {
43    #[inline]
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        write!(f, "{}&{}={}", self.path, Self::SEPARATOR, self.name)
46    }
47}
48debugdisplay!(ModuleURI);
49
50/*
51#[derive(Copy,Clone, PartialEq, Eq, Hash)]
52pub struct ModuleURIRef<'a> {
53    pub(in crate::uris) path: PathURIRef<'a>,
54    pub(in crate::uris) name: &'a Name,
55    pub(in crate::uris) language: Language,
56}
57impl Display for ModuleURIRef<'_> {
58    #[inline]
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        write!(
61            f,
62            "{}&{}={}&{}={}",
63            self.path,
64            ModuleURI::SEPARATOR,
65            self.name,
66            Language::SEPARATOR,
67            self.language
68        )
69    }
70}
71debugdisplay!(ModuleURIRef<'_>);
72*/
73
74impl URITrait for ModuleURI {
75    type Ref<'a> = &'a Self; //ModuleURIRef<'a>;
76}
77
78pub type ModuleURIRef<'a> = &'a ModuleURI;
79
80impl<'a> URIRefTrait<'a> for ModuleURIRef<'a> {
81    type Owned = ModuleURI;
82    #[inline]
83    fn owned(self) -> Self::Owned {
84        self.clone()
85    }
86}
87/*
88impl<'a> URIRefTrait<'a> for ModuleURIRef<'a> {
89    type Owned = ModuleURI;
90    fn owned(self) -> Self::Owned {
91        ModuleURI {
92            path: self.path.owned(),
93            name: self.name.clone(),
94            language: self.language,
95        }
96    }
97}
98*/
99impl From<ModuleURI> for URI {
100    #[inline]
101    fn from(value: ModuleURI) -> Self {
102        Self::Content(ContentURI::Module(value))
103    }
104}
105impl<'a> From<ModuleURIRef<'a>> for URIRef<'a> {
106    #[inline]
107    fn from(value: ModuleURIRef<'a>) -> Self {
108        URIRef::Content(ContentURIRef::Module(value))
109    }
110}
111/*
112impl<'a> URIOrRefTrait for ModuleURIRef<'a> {
113    #[inline]
114    fn base(&self) -> &'a BaseURI {
115        &self.path.archive.base
116    }
117    #[inline]
118    fn as_uri(&self) -> URIRef<'a> {
119        URIRef::Content(ContentURIRef::Module(*self))
120    }
121}
122
123impl<'a> From<&'a ModuleURI> for ModuleURIRef<'a> {
124    #[inline]
125    fn from(value: &'a ModuleURI) -> Self {
126        Self {
127            path: value.as_path(),
128            name: &value.name,
129            language: value.language,
130        }
131    }
132}
133*/
134
135impl URIOrRefTrait for ModuleURI {
136    #[inline]
137    fn base(&self) -> &BaseURI {
138        self.path.base()
139    }
140    #[inline]
141    fn as_uri(&self) -> URIRef {
142        URIRef::Content(self.as_content())
143    }
144}
145impl ContentURITrait for ModuleURI {
146    #[inline]
147    fn as_content(&self) -> ContentURIRef {
148        ContentURIRef::Module(self)
149    }
150    #[inline]
151    fn module(&self) -> ModuleURIRef {
152        self
153    }
154}
155impl<'a> ContentURITrait for ModuleURIRef<'a> {
156    #[inline]
157    fn as_content(&self) -> ContentURIRef<'a> {
158        ContentURIRef::Module(self)
159    }
160    #[inline]
161    fn module(&self) -> Self {
162        self
163    }
164}
165
166impl ModuleURI {
167    #[inline]
168    #[must_use]
169    pub const fn name(&self) -> &Name {
170        &self.name
171    }
172    pub(super) fn pre_parse<R>(
173        s: &str,
174        uri_kind: &'static str,
175        f: impl FnOnce(Self, Split<char>) -> Result<R, URIParseError>,
176    ) -> Result<R, URIParseError> {
177        PathURI::pre_parse(s, uri_kind, |path, next, mut split| {
178            let Some(m) = next.or_else(|| split.next()) else {
179                return Err(URIParseError::MissingPartFor {
180                    uri_kind,
181                    part: "module name",
182                    original: s.to_string(),
183                });
184            };
185            m.strip_prefix(concatcp!(ModuleURI::SEPARATOR, "="))
186                .map_or_else(
187                    || {
188                        Err(URIParseError::MissingPartFor {
189                            uri_kind,
190                            part: "module name",
191                            original: s.to_string(),
192                        })
193                    },
194                    |name| {
195                        f(
196                            Self {
197                                path,
198                                name: name.parse()?,
199                            },
200                            split,
201                        )
202                    },
203                )
204        })
205    }
206}
207impl FromStr for ModuleURI {
208    type Err = URIParseError;
209    fn from_str(s: &str) -> Result<Self, Self::Err> {
210        Self::pre_parse(s, "module uri", |u, mut split| {
211            if split.next().is_some() {
212                return Err(URIParseError::TooManyPartsFor {
213                    uri_kind: "module uri",
214                    original: s.to_string(),
215                });
216            }
217            Ok(u)
218        })
219    }
220}
221impl ArchiveURITrait for ModuleURI {
222    #[inline]
223    fn archive_uri(&self) -> ArchiveURIRef {
224        self.path.archive_uri()
225    }
226}
227impl PathURITrait for ModuleURI {
228    #[inline]
229    fn as_path(&self) -> PathURIRef {
230        self.path.as_path()
231    }
232    #[inline]
233    fn path(&self) -> Option<&Name> {
234        self.path.path()
235    }
236}
237impl<'a> ArchiveURITrait for ModuleURIRef<'a> {
238    #[inline]
239    fn archive_uri(&self) -> ArchiveURIRef<'a> {
240        self.path.archive_uri()
241    }
242}
243impl<'a> PathURITrait for ModuleURIRef<'a> {
244    #[inline]
245    fn as_path(&self) -> PathURIRef<'a> {
246        (*self).as_path()
247    }
248    #[inline]
249    fn path(&self) -> Option<&'a Name> {
250        self.path.path.as_ref()
251    }
252}
253
254#[cfg(feature = "serde")]
255mod serde_impl {
256    use crate::uris::{serialize, ModuleURI, ModuleURIRef};
257    serialize!(DE ModuleURI);
258    //serialize!(ModuleURIRef<'_>);
259}