flams_ontology/uris/content/
symbols.rs

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