1use std::{
2 collections::{BTreeMap, HashMap},
3 fmt::Debug,
4 hash::Hash,
5 marker::PhantomData,
6};
7
8use serde::{de::Visitor, ser::SerializeSeq, Deserialize, Serialize};
9
10pub mod xsd;
11
12#[derive(PartialEq, Eq, Clone, Debug, Hash)]
13pub enum Remotable<T> {
14 Remote(url::Url),
15 Inline(T),
16}
17
18pub trait ObjectId {
19 fn object_id(&self) -> Option<&url::Url>;
20}
21
22impl<T: ObjectId> ObjectId for Remotable<T> {
23 fn object_id(&self) -> Option<&url::Url> {
24 match self {
25 Remotable::Remote(id) => Some(id),
26 Remotable::Inline(object) => object.object_id(),
27 }
28 }
29}
30
31impl<T: Serialize> Serialize for Remotable<T> {
32 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
33 where
34 S: serde::Serializer,
35 {
36 match self {
37 Remotable::Inline(inline) => inline.serialize(serializer),
38 Remotable::Remote(remote) => remote.serialize(serializer),
39 }
40 }
41}
42
43impl<'de, T: Deserialize<'de>> Deserialize<'de> for Remotable<T> {
44 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
45 where
46 D: serde::Deserializer<'de>,
47 {
48 let value = serde_value::Value::deserialize(deserializer)?;
49 let deserializer = serde_value::ValueDeserializer::<D::Error>::new(value.clone());
50 match T::deserialize(deserializer) {
51 Ok(inline) => Ok(Self::Inline(inline)),
52 Err(inline_err) => url::Url::deserialize(serde_value::ValueDeserializer::new(value))
53 .map_err(|e: D::Error| serde::de::Error::custom(format!("{inline_err} & {e}")))
54 .map(Self::Remote),
55 }
56 }
57}
58
59#[derive(PartialEq, Eq, Clone, Debug, Hash)]
60pub struct Property<T>(pub Vec<T>);
61
62impl<T: Serialize> Serialize for Property<T> {
63 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
64 where
65 S: serde::Serializer,
66 {
67 if let [inner] = &self.0[..] {
68 inner.serialize(serializer)
69 } else if self.0.len() > 1 {
70 self.0.serialize(serializer)
71 } else {
72 serializer.serialize_none()
73 }
74 }
75}
76
77impl<'de, T: Deserialize<'de>> Deserialize<'de> for Property<T> {
78 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
79 where
80 D: serde::Deserializer<'de>,
81 {
82 let content = serde::__private::de::Content::deserialize(deserializer)?;
83 let deserializer = serde::__private::de::ContentRefDeserializer::<D::Error>::new(&content);
84 match Vec::<T>::deserialize(deserializer) {
85 Ok(inner) => Ok(Self(inner)),
86 Err(seq_err) => match Option::<T>::deserialize(deserializer) {
87 Ok(inner) => Ok(Self(inner.into_iter().collect())),
88 Err(opt_err) => Err(serde::de::Error::custom(format!("{seq_err} & {opt_err}"))),
89 },
90 }
91 }
92}
93
94impl<T> Default for Property<T> {
95 fn default() -> Self {
96 Self(Default::default())
97 }
98}
99
100#[derive(PartialEq, Clone, Debug)]
101pub enum Or<T, U> {
102 Prim(T),
103 Snd(U),
104}
105
106impl<'de, L: Deserialize<'de>, R: Deserialize<'de>> Deserialize<'de> for Or<L, R> {
107 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
108 where
109 D: serde::Deserializer<'de>,
110 {
111 let content = serde::__private::de::Content::deserialize(deserializer)?;
112 let deserializer = serde::__private::de::ContentRefDeserializer::<D::Error>::new(&content);
113 match L::deserialize(deserializer) {
114 Ok(left) => Ok(Self::Prim(left)),
115 Err(left_err) => R::deserialize(deserializer)
116 .map_err(|right_err| {
117 serde::de::Error::custom(format!("{left_err} and {right_err}"))
118 })
119 .map(Self::Snd),
120 }
121 }
122}
123
124impl<T: Serialize, U: Serialize> Serialize for Or<T, U> {
125 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
126 where
127 S: serde::Serializer,
128 {
129 match self {
130 Self::Prim(value) => value.serialize(serializer),
131 Self::Snd(value) => value.serialize(serializer),
132 }
133 }
134}
135
136pub type Untypable<T> = Or<T, serde_json::Value>;
138
139impl<L, R> Or<L, R> {
140 pub fn prim(&self) -> Option<&L> {
141 match self {
142 Self::Prim(l) => Some(l),
143 Self::Snd(_) => None,
144 }
145 }
146 pub fn snd(&self) -> Option<&R> {
147 match self {
148 Self::Prim(_) => None,
149 Self::Snd(r) => Some(r),
150 }
151 }
152}
153
154impl<P, S> From<P> for Or<P, S> {
155 fn from(value: P) -> Self {
156 Or::Prim(value)
157 }
158}
159
160impl<L: Default, R> Default for Or<L, R> {
161 fn default() -> Self {
162 Or::Prim(L::default())
163 }
164}
165
166pub trait SkipSerialization {
167 fn should_skip(&self) -> bool;
168}
169
170impl<T> SkipSerialization for Option<T> {
171 fn should_skip(&self) -> bool {
172 self.is_none()
173 }
174}
175
176impl<T> SkipSerialization for Property<T> {
177 fn should_skip(&self) -> bool {
178 self.0.is_empty()
179 }
180}
181
182impl<K, V> SkipSerialization for HashMap<K, V> {
183 fn should_skip(&self) -> bool {
184 self.is_empty()
185 }
186}
187
188#[derive(Debug, Clone, PartialEq, Default)]
189pub struct LangContainer<T> {
190 pub default: Option<T>,
191 pub per_lang: HashMap<String, T>,
192}
193
194impl<'de, T: Deserialize<'de>> Deserialize<'de> for LangContainer<T> {
195 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
196 where
197 D: serde::Deserializer<'de>,
198 {
199 let value = serde_value::Value::deserialize(deserializer)?;
200 let deserializer = serde_value::ValueDeserializer::<D::Error>::new(value.clone());
201 match T::deserialize(deserializer) {
202 Ok(inline) => Ok(Self {
203 default: Some(inline),
204 per_lang: Default::default(),
205 }),
206 Err(inline_err) => {
207 HashMap::<String, T>::deserialize(serde_value::ValueDeserializer::new(value))
208 .map_err(|e: D::Error| serde::de::Error::custom(format!("{inline_err} & {e}")))
209 .map(|per_lang| Self {
210 default: Default::default(),
211 per_lang,
212 })
213 }
214 }
215 }
216}
217
218impl<T> LangContainer<T> {
219 pub fn merge(&mut self, other: Self) {
220 match (&mut self.default, other.default) {
221 (Some(x), Some(y)) => *x = y,
222 (None, Some(y)) => self.default = Some(y),
223 (_, None) => (),
224 }
225 self.per_lang.extend(other.per_lang)
226 }
227}
228
229impl<T: MergeableProperty> LangContainer<T> {
230 pub fn deep_merge(&mut self, other: Self) {
231 match (&mut self.default, other.default) {
232 (Some(x), Some(y)) => x.merge(y),
233 (None, Some(y)) => self.default = Some(y),
234 (_, None) => (),
235 }
236 for (k, v) in other.per_lang {
237 match &mut self.per_lang.get_mut(&k) {
238 Some(occupied) => occupied.merge(v),
239 None => {
240 self.per_lang.insert(k, v);
241 }
242 }
243 }
244 }
245}
246
247pub trait MergeableProperty {
248 fn merge(&mut self, other: Self);
249}
250
251impl<T> MergeableProperty for Property<T> {
252 fn merge(&mut self, other: Self) {
253 self.0.extend(other.0)
254 }
255}
256
257impl<K: Eq + Hash, V> MergeableProperty for HashMap<K, V> {
258 fn merge(&mut self, other: Self) {
259 self.extend(other)
260 }
261}
262
263impl<T: MergeableProperty> MergeableProperty for Option<T> {
264 fn merge(&mut self, other: Self) {
265 match (self.as_mut(), other) {
266 (Some(x), Some(y)) => x.merge(y),
267 (None, Some(y)) => {
268 *self = Some(y);
269 }
270 (Some(_), None) => (),
271 (None, None) => (),
272 }
273 }
274}
275
276#[derive(PartialEq, Eq, Clone, Debug)]
277pub struct Context {
278 urls: Vec<url::Url>,
279 inline: HashMap<String, serde_json::Value>,
280}
281
282impl Serialize for Context {
283 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
284 where
285 S: serde::Serializer,
286 {
287 if self.inline.is_empty() {
288 if let &[url] = &self.urls.as_slice() {
289 url.serialize(serializer)
290 } else {
291 self.urls.serialize(serializer)
292 }
293 } else if self.urls.is_empty() {
294 self.inline.serialize(serializer)
295 } else {
296 let mut serializer = serializer.serialize_seq(Some(self.urls.len() + 1))?;
297 for url in &self.urls {
298 serializer.serialize_element(url)?;
299 }
300 serializer.serialize_element(&self.inline)?;
301 serializer.end()
302 }
303 }
304}
305
306enum ContextArrayElement {
307 Url(url::Url),
308 Inline(HashMap<String, serde_json::Value>),
309}
310
311struct ContextArrayElementVisitor;
312impl<'de> Visitor<'de> for ContextArrayElementVisitor {
313 type Value = ContextArrayElement;
314 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
315 formatter.write_str("element of @context[]")
316 }
317
318 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
319 where
320 A: serde::de::MapAccess<'de>,
321 {
322 let mut r = HashMap::new();
323 while let Some((k, v)) = map.next_entry::<String, serde_json::Value>()? {
324 r.insert(k, v);
325 }
326 Ok(ContextArrayElement::Inline(r))
327 }
328
329 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
330 where
331 E: serde::de::Error,
332 {
333 Ok(ContextArrayElement::Url(
334 v.parse().map_err(serde::de::Error::custom)?,
335 ))
336 }
337}
338
339impl<'de> Deserialize<'de> for ContextArrayElement {
340 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
341 where
342 D: serde::Deserializer<'de>,
343 {
344 deserializer.deserialize_any(ContextArrayElementVisitor)
345 }
346}
347
348struct ContextVisitor;
349impl<'de> Visitor<'de> for ContextVisitor {
350 type Value = Context;
351
352 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
353 formatter.write_str("@context")
354 }
355
356 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
357 where
358 E: serde::de::Error,
359 {
360 let visitor = ContextArrayElementVisitor;
361 let ContextArrayElement::Url(url) = visitor.visit_str(v)? else {
362 unreachable!()
363 };
364 Ok(Self::Value {
365 urls: vec![url],
366 inline: Default::default(),
367 })
368 }
369
370 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
371 where
372 A: serde::de::SeqAccess<'de>,
373 {
374 let mut inline = HashMap::new();
375 let mut urls = Vec::new();
376 while let Some(element) = seq.next_element::<ContextArrayElement>()? {
377 match element {
378 ContextArrayElement::Inline(new) => {
379 inline.extend(new);
380 }
381 ContextArrayElement::Url(url) => {
382 urls.push(url);
383 }
384 }
385 }
386 Ok(Self::Value { inline, urls })
387 }
388
389 fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
390 where
391 A: serde::de::MapAccess<'de>,
392 {
393 let visitor = ContextArrayElementVisitor;
394 let ContextArrayElement::Inline(inline) = visitor.visit_map(map)? else {
395 unreachable!()
396 };
397 Ok(Self::Value {
398 inline,
399 urls: Default::default(),
400 })
401 }
402}
403
404impl<'de> Deserialize<'de> for Context {
405 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
406 where
407 D: serde::Deserializer<'de>,
408 {
409 deserializer.deserialize_any(ContextVisitor)
410 }
411}
412
413#[derive(Serialize, Deserialize)]
414pub struct WithContext<T> {
415 #[serde(rename = "@context", skip_serializing_if = "Option::is_none")]
416 pub context: Option<Context>,
417 #[serde(flatten)]
418 pub body: T,
419}
420
421pub struct TaggedContentVisitor<T> {
422 name: &'static str,
423 tag: &'static str,
424 _tag: PhantomData<T>,
425}
426
427impl<T> TaggedContentVisitor<T> {
428 pub fn new(name: &'static str, tag: &'static str) -> Self {
429 Self {
430 name,
431 tag,
432 _tag: Default::default(),
433 }
434 }
435}
436
437impl<'de, T: Deserialize<'de> + Debug + Default> Visitor<'de> for TaggedContentVisitor<T> {
438 type Value = (T, serde_value::Value);
439
440 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
441 formatter.write_str(self.name)
442 }
443
444 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
445 where
446 A: serde::de::MapAccess<'de>,
447 {
448 let mut content = BTreeMap::new();
449 let mut tag = None;
450 while let Some((k, v)) = map.next_entry::<serde_value::Value, serde_value::Value>()? {
451 if let serde_value::Value::String(label) = &k {
452 if label == self.tag {
453 tag = Some(T::deserialize(serde_value::ValueDeserializer::new(
454 v.clone(),
455 ))?)
456 }
457 }
458 content.insert(k, v);
459 }
460 Ok((tag.unwrap_or_default(), serde_value::Value::Map(content)))
461 }
462}