flams_ontology/uris/content/
modules.rs1use 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
50impl URITrait for ModuleURI {
75 type Ref<'a> = &'a Self; }
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}
87impl 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}
111impl 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 }