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