Skip to main content

mf2_model/
json.rs

1//! Feature `serde`: (de)serialization as the JSON of
2//! `spec/data-model/message.json`.
3//!
4//! * Objects carry their `type` tag (`"message"`, `"select"`, `"input"`,
5//!   `"local"`, `"expression"`, `"markup"`, `"function"`, `"literal"`,
6//!   `"variable"`, `"*"`); variants have none.
7//! * A catch-all key is `{"type": "*"}` (plus `"value"` if it has one); an
8//!   attribute without a value is `true`.
9//! * Serialization writes `declarations`, `options` and `attributes` even when
10//!   empty. A model with two options (or two attributes) of the same name
11//!   cannot be serialized: a JSON object cannot hold both.
12//! * Deserialization accepts the schema's relaxations (missing empty
13//!   `declarations`, `options`, `attributes`), ignores unknown fields (data
14//!   model, "Model Extensions"), borrows strings from the input where the
15//!   deserializer allows it, and normalizes patterns as [`Pattern::push`]
16//!   does (empty text dropped, adjacent text merged).
17
18use alloc::borrow::Cow;
19use alloc::vec::Vec;
20
21use serde::de::{self, Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
22use serde::ser::{self, Serialize, SerializeMap, SerializeSeq, Serializer};
23
24use crate::expression::{
25    Attributes, Expression, FunctionExpression, FunctionRef, Literal, LiteralExpression, Markup,
26    MarkupKind, OptionValue, Options, VariableExpression, VariableRef,
27};
28use crate::message::{
29    CatchAllKey, Declaration, InputDeclaration, Key, LocalDeclaration, Message, PatternMessage,
30    SelectMessage, Variant,
31};
32use crate::pattern::{Pattern, PatternPart};
33
34// ───────────────────────────── serialization ─────────────────────────────
35
36impl Serialize for Message<'_> {
37    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
38        match self {
39            Message::Pattern(m) => m.serialize(s),
40            Message::Select(m) => m.serialize(s),
41        }
42    }
43}
44
45impl Serialize for PatternMessage<'_> {
46    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
47        let mut map = s.serialize_map(Some(3))?;
48        map.serialize_entry("type", "message")?;
49        map.serialize_entry("declarations", &self.declarations)?;
50        map.serialize_entry("pattern", &self.pattern)?;
51        map.end()
52    }
53}
54
55impl Serialize for SelectMessage<'_> {
56    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
57        let mut map = s.serialize_map(Some(4))?;
58        map.serialize_entry("type", "select")?;
59        map.serialize_entry("declarations", &self.declarations)?;
60        map.serialize_entry("selectors", &self.selectors)?;
61        map.serialize_entry("variants", &self.variants)?;
62        map.end()
63    }
64}
65
66impl Serialize for Declaration<'_> {
67    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
68        match self {
69            Declaration::Input(d) => d.serialize(s),
70            Declaration::Local(d) => d.serialize(s),
71        }
72    }
73}
74
75impl Serialize for InputDeclaration<'_> {
76    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
77        let mut map = s.serialize_map(Some(3))?;
78        map.serialize_entry("type", "input")?;
79        map.serialize_entry("name", &*self.name)?;
80        map.serialize_entry("value", &self.value)?;
81        map.end()
82    }
83}
84
85impl Serialize for LocalDeclaration<'_> {
86    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
87        let mut map = s.serialize_map(Some(3))?;
88        map.serialize_entry("type", "local")?;
89        map.serialize_entry("name", &*self.name)?;
90        map.serialize_entry("value", &self.value)?;
91        map.end()
92    }
93}
94
95impl Serialize for Variant<'_> {
96    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
97        let mut map = s.serialize_map(Some(2))?;
98        map.serialize_entry("keys", &self.keys)?;
99        map.serialize_entry("value", &self.value)?;
100        map.end()
101    }
102}
103
104impl Serialize for Key<'_> {
105    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
106        match self {
107            Key::Literal(l) => l.serialize(s),
108            Key::CatchAll(c) => c.serialize(s),
109        }
110    }
111}
112
113impl Serialize for CatchAllKey<'_> {
114    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
115        let mut map = s.serialize_map(Some(1 + usize::from(self.value.is_some())))?;
116        map.serialize_entry("type", "*")?;
117        if let Some(v) = &self.value {
118            map.serialize_entry("value", &**v)?;
119        }
120        map.end()
121    }
122}
123
124impl Serialize for Pattern<'_> {
125    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
126        let mut seq = s.serialize_seq(Some(self.len()))?;
127        for part in self.parts() {
128            seq.serialize_element(part)?;
129        }
130        seq.end()
131    }
132}
133
134impl Serialize for PatternPart<'_> {
135    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
136        match self {
137            PatternPart::Text(t) => s.serialize_str(t),
138            PatternPart::Expression(e) => e.serialize(s),
139            PatternPart::Markup(m) => m.serialize(s),
140        }
141    }
142}
143
144#[derive(Clone, Copy)]
145enum ArgRef<'r, 'a> {
146    Literal(&'r Literal<'a>),
147    Variable(&'r VariableRef<'a>),
148}
149
150fn expression_map<S: Serializer>(
151    s: S,
152    arg: Option<ArgRef<'_, '_>>,
153    function: Option<&FunctionRef<'_>>,
154    attributes: &Attributes<'_>,
155) -> Result<S::Ok, S::Error> {
156    let len = 2 + usize::from(arg.is_some()) + usize::from(function.is_some());
157    let mut map = s.serialize_map(Some(len))?;
158    map.serialize_entry("type", "expression")?;
159    match arg {
160        Some(ArgRef::Literal(l)) => map.serialize_entry("arg", l)?,
161        Some(ArgRef::Variable(v)) => map.serialize_entry("arg", v)?,
162        None => {}
163    }
164    if let Some(f) = function {
165        map.serialize_entry("function", f)?;
166    }
167    map.serialize_entry("attributes", attributes)?;
168    map.end()
169}
170
171impl Serialize for Expression<'_> {
172    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
173        match self {
174            Expression::Literal(e) => e.serialize(s),
175            Expression::Variable(e) => e.serialize(s),
176            Expression::Function(e) => e.serialize(s),
177        }
178    }
179}
180
181impl Serialize for LiteralExpression<'_> {
182    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
183        expression_map(
184            s,
185            Some(ArgRef::Literal(&self.arg)),
186            self.function.as_ref(),
187            &self.attributes,
188        )
189    }
190}
191
192impl Serialize for VariableExpression<'_> {
193    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
194        expression_map(
195            s,
196            Some(ArgRef::Variable(&self.arg)),
197            self.function.as_ref(),
198            &self.attributes,
199        )
200    }
201}
202
203impl Serialize for FunctionExpression<'_> {
204    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
205        expression_map(s, None, Some(&self.function), &self.attributes)
206    }
207}
208
209impl Serialize for Literal<'_> {
210    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
211        let mut map = s.serialize_map(Some(2))?;
212        map.serialize_entry("type", "literal")?;
213        map.serialize_entry("value", &*self.value)?;
214        map.end()
215    }
216}
217
218impl Serialize for VariableRef<'_> {
219    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
220        let mut map = s.serialize_map(Some(2))?;
221        map.serialize_entry("type", "variable")?;
222        map.serialize_entry("name", &*self.name)?;
223        map.end()
224    }
225}
226
227impl Serialize for FunctionRef<'_> {
228    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
229        let mut map = s.serialize_map(Some(3))?;
230        map.serialize_entry("type", "function")?;
231        map.serialize_entry("name", &*self.name)?;
232        map.serialize_entry("options", &self.options)?;
233        map.end()
234    }
235}
236
237impl Serialize for OptionValue<'_> {
238    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
239        match self {
240            OptionValue::Literal(l) => l.serialize(s),
241            OptionValue::Variable(v) => v.serialize(s),
242        }
243    }
244}
245
246/// `true` if two names in `names` are equal (bytewise): pairwise for a few,
247/// sorted beyond that, so a large map cannot make serialization quadratic.
248fn has_duplicate<'n, I: Iterator<Item = &'n str> + Clone>(names: &I) -> bool {
249    if names.clone().nth(16).is_none() {
250        return names
251            .clone()
252            .enumerate()
253            .any(|(i, a)| names.clone().skip(i + 1).any(|b| a == b));
254    }
255    let mut sorted: Vec<&str> = names.clone().collect();
256    sorted.sort_unstable();
257    sorted.windows(2).any(|w| w[0] == w[1])
258}
259
260impl Serialize for Options<'_> {
261    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
262        if has_duplicate(&self.0.iter().map(|(k, _)| k.as_ref())) {
263            return Err(ser::Error::custom(
264                "duplicate option name: a JSON object cannot hold both options",
265            ));
266        }
267        let mut map = s.serialize_map(Some(self.len()))?;
268        for (k, v) in self.iter() {
269            map.serialize_entry(k, v)?;
270        }
271        map.end()
272    }
273}
274
275impl Serialize for Attributes<'_> {
276    /// A repeated name writes only its last occurrence: the syntax allows
277    /// the repeat (unique names are only a SHOULD) and only the last of a
278    /// repeated attribute counts (`syntax.md`, "Attributes"), while a JSON object holds a name once. The model keeps
279    /// every occurrence, as written.
280    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
281        let names = self.0.iter().map(|(k, _)| k.as_ref());
282        let last = |i: usize, k: &str| !self.0[i + 1..].iter().any(|(j, _)| j.as_ref() == k);
283        let kept: Vec<usize> = if has_duplicate(&names) {
284            (0..self.len())
285                .filter(|&i| last(i, self.0[i].0.as_ref()))
286                .collect()
287        } else {
288            (0..self.len()).collect()
289        };
290        let mut map = s.serialize_map(Some(kept.len()))?;
291        for i in kept {
292            let (k, v) = &self.0[i];
293            match v {
294                Some(l) => map.serialize_entry(k, l)?,
295                None => map.serialize_entry(k, &true)?,
296            }
297        }
298        map.end()
299    }
300}
301
302impl Serialize for Markup<'_> {
303    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
304        let mut map = s.serialize_map(Some(5))?;
305        map.serialize_entry("type", "markup")?;
306        map.serialize_entry("kind", self.kind.as_json())?;
307        map.serialize_entry("name", &*self.name)?;
308        map.serialize_entry("options", &self.options)?;
309        map.serialize_entry("attributes", &self.attributes)?;
310        map.end()
311    }
312}
313
314impl MarkupKind {
315    fn as_json(self) -> &'static str {
316        match self {
317            MarkupKind::Open => "open",
318            MarkupKind::Standalone => "standalone",
319            MarkupKind::Close => "close",
320        }
321    }
322}
323
324// ──────────────────────────── deserialization ────────────────────────────
325
326/// A string borrowed from the input when the deserializer allows it.
327struct CowStr<'de>(Cow<'de, str>);
328
329impl<'de> Deserialize<'de> for CowStr<'de> {
330    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
331        struct V;
332        impl<'de> Visitor<'de> for V {
333            type Value = CowStr<'de>;
334            fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
335                f.write_str("a string")
336            }
337            fn visit_borrowed_str<E: de::Error>(self, v: &'de str) -> Result<Self::Value, E> {
338                Ok(CowStr(Cow::Borrowed(v)))
339            }
340            fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
341                Ok(CowStr(Cow::Owned(v.into())))
342            }
343            fn visit_string<E: de::Error>(
344                self,
345                v: alloc::string::String,
346            ) -> Result<Self::Value, E> {
347                Ok(CowStr(Cow::Owned(v)))
348            }
349        }
350        d.deserialize_str(V)
351    }
352}
353
354/// A JSON value, strings borrowed where possible, object members in order
355/// (duplicates kept).
356enum Value<'de> {
357    Null,
358    Bool(bool),
359    Number,
360    Str(Cow<'de, str>),
361    Seq(Vec<Value<'de>>),
362    Map(Vec<(Cow<'de, str>, Value<'de>)>),
363}
364
365impl<'de> Deserialize<'de> for Value<'de> {
366    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
367        struct V;
368        impl<'de> Visitor<'de> for V {
369            type Value = Value<'de>;
370            fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
371                f.write_str("a JSON value")
372            }
373            fn visit_bool<E: de::Error>(self, v: bool) -> Result<Self::Value, E> {
374                Ok(Value::Bool(v))
375            }
376            fn visit_i64<E: de::Error>(self, _: i64) -> Result<Self::Value, E> {
377                Ok(Value::Number)
378            }
379            fn visit_u64<E: de::Error>(self, _: u64) -> Result<Self::Value, E> {
380                Ok(Value::Number)
381            }
382            fn visit_f64<E: de::Error>(self, _: f64) -> Result<Self::Value, E> {
383                Ok(Value::Number)
384            }
385            fn visit_borrowed_str<E: de::Error>(self, v: &'de str) -> Result<Self::Value, E> {
386                Ok(Value::Str(Cow::Borrowed(v)))
387            }
388            fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
389                Ok(Value::Str(Cow::Owned(v.into())))
390            }
391            fn visit_string<E: de::Error>(
392                self,
393                v: alloc::string::String,
394            ) -> Result<Self::Value, E> {
395                Ok(Value::Str(Cow::Owned(v)))
396            }
397            fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> {
398                Ok(Value::Null)
399            }
400            fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
401                Ok(Value::Null)
402            }
403            fn visit_some<D2: Deserializer<'de>>(self, d: D2) -> Result<Self::Value, D2::Error> {
404                Value::deserialize(d)
405            }
406            fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
407                let mut out = Vec::with_capacity(seq.size_hint().unwrap_or(0).min(64));
408                while let Some(v) = seq.next_element()? {
409                    out.push(v);
410                }
411                Ok(Value::Seq(out))
412            }
413            fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
414                let mut out = Vec::with_capacity(map.size_hint().unwrap_or(0).min(64));
415                while let Some(CowStr(k)) = map.next_key()? {
416                    out.push((k, map.next_value()?));
417                }
418                Ok(Value::Map(out))
419            }
420        }
421        d.deserialize_any(V)
422    }
423}
424
425type Members<'de> = Vec<(Cow<'de, str>, Value<'de>)>;
426
427/// The members of an object, with one-shot field extraction.
428struct Obj<'de>(Members<'de>);
429
430impl<'de> Obj<'de> {
431    fn new<E: de::Error>(v: Value<'de>, what: &'static str) -> Result<Self, E> {
432        match v {
433            Value::Map(m) => Ok(Obj(m)),
434            _ => Err(E::custom(what)),
435        }
436    }
437
438    /// Removes and returns the first member named `name`.
439    fn take(&mut self, name: &str) -> Option<Value<'de>> {
440        let i = self.0.iter().position(|(k, _)| k == name)?;
441        Some(self.0.swap_remove(i).1)
442    }
443
444    fn string<E: de::Error>(&mut self, name: &str, what: &'static str) -> Result<Cow<'de, str>, E> {
445        match self.take(name) {
446            Some(Value::Str(s)) => Ok(s),
447            _ => Err(E::custom(what)),
448        }
449    }
450
451    /// The `type` tag.
452    fn tag<E: de::Error>(&mut self) -> Result<Cow<'de, str>, E> {
453        self.string("type", "an object needs a string `type`")
454    }
455
456    fn expect_tag<E: de::Error>(&mut self, tag: &str, what: &'static str) -> Result<(), E> {
457        if self.tag::<E>()? == tag {
458            Ok(())
459        } else {
460            Err(E::custom(what))
461        }
462    }
463
464    /// An array member that may be missing (the schema's relaxation).
465    fn seq_or_empty<E: de::Error>(
466        &mut self,
467        name: &str,
468        what: &'static str,
469    ) -> Result<Vec<Value<'de>>, E> {
470        match self.take(name) {
471            None => Ok(Vec::new()),
472            Some(Value::Seq(v)) => Ok(v),
473            Some(_) => Err(E::custom(what)),
474        }
475    }
476
477    fn seq<E: de::Error>(&mut self, name: &str, what: &'static str) -> Result<Vec<Value<'de>>, E> {
478        match self.take(name) {
479            Some(Value::Seq(v)) => Ok(v),
480            _ => Err(E::custom(what)),
481        }
482    }
483
484    /// An object member that may be missing (the schema's relaxation).
485    fn map_or_empty<E: de::Error>(
486        &mut self,
487        name: &str,
488        what: &'static str,
489    ) -> Result<Members<'de>, E> {
490        match self.take(name) {
491            None => Ok(Vec::new()),
492            Some(Value::Map(m)) => Ok(m),
493            Some(_) => Err(E::custom(what)),
494        }
495    }
496}
497
498fn message<E: de::Error>(v: Value<'_>) -> Result<Message<'_>, E> {
499    let mut o = Obj::new(v, "a message must be an object")?;
500    let tag = o.tag::<E>()?;
501    let declarations = o
502        .seq_or_empty::<E>("declarations", "`declarations` must be an array")?
503        .into_iter()
504        .map(declaration)
505        .collect::<Result<Vec<_>, E>>()?;
506    match &*tag {
507        "message" => Ok(Message::Pattern(PatternMessage {
508            declarations,
509            pattern: pattern(
510                o.take("pattern")
511                    .ok_or_else(|| E::custom("a message needs a `pattern`"))?,
512            )?,
513        })),
514        "select" => {
515            let selectors = o
516                .seq::<E>("selectors", "a select message needs a `selectors` array")?
517                .into_iter()
518                .map(variable_ref)
519                .collect::<Result<Vec<_>, E>>()?;
520            let variants = o
521                .seq::<E>("variants", "a select message needs a `variants` array")?
522                .into_iter()
523                .map(variant)
524                .collect::<Result<Vec<_>, E>>()?;
525            Ok(Message::Select(SelectMessage {
526                declarations,
527                selectors,
528                variants,
529            }))
530        }
531        _ => Err(E::custom(
532            "a message's `type` must be \"message\" or \"select\"",
533        )),
534    }
535}
536
537fn declaration<E: de::Error>(v: Value<'_>) -> Result<Declaration<'_>, E> {
538    let mut o = Obj::new(v, "a declaration must be an object")?;
539    let tag = o.tag::<E>()?;
540    let name = o.string::<E>("name", "a declaration needs a string `name`")?;
541    let value = o
542        .take("value")
543        .ok_or_else(|| E::custom("a declaration needs a `value`"))?;
544    match &*tag {
545        "input" => {
546            let Expression::Variable(value) = expression(value)? else {
547                return Err(E::custom(
548                    "an input declaration's value needs a variable `arg`",
549                ));
550            };
551            if value.arg.name != name {
552                return Err(E::custom(
553                    "an input declaration's `name` must equal its variable's name",
554                ));
555            }
556            Ok(Declaration::Input(InputDeclaration { name, value }))
557        }
558        "local" => Ok(Declaration::Local(LocalDeclaration {
559            name,
560            value: expression(value)?,
561        })),
562        _ => Err(E::custom(
563            "a declaration's `type` must be \"input\" or \"local\"",
564        )),
565    }
566}
567
568fn variant<E: de::Error>(v: Value<'_>) -> Result<Variant<'_>, E> {
569    let mut o = Obj::new(v, "a variant must be an object")?;
570    let keys = o
571        .seq::<E>("keys", "a variant needs a `keys` array")?
572        .into_iter()
573        .map(key)
574        .collect::<Result<Vec<_>, E>>()?;
575    let value = pattern(
576        o.take("value")
577            .ok_or_else(|| E::custom("a variant needs a `value` pattern"))?,
578    )?;
579    Ok(Variant { keys, value })
580}
581
582fn key<E: de::Error>(v: Value<'_>) -> Result<Key<'_>, E> {
583    let mut o = Obj::new(v, "a key must be an object")?;
584    match &*o.tag::<E>()? {
585        "literal" => Ok(Key::Literal(Literal {
586            value: o.string::<E>("value", "a literal needs a string `value`")?,
587        })),
588        "*" => {
589            let value = match o.take("value") {
590                None => None,
591                Some(Value::Str(s)) => Some(s),
592                Some(_) => return Err(E::custom("a catch-all key's `value` must be a string")),
593            };
594            Ok(Key::CatchAll(CatchAllKey { value }))
595        }
596        _ => Err(E::custom("a key's `type` must be \"literal\" or \"*\"")),
597    }
598}
599
600fn pattern<E: de::Error>(v: Value<'_>) -> Result<Pattern<'_>, E> {
601    let Value::Seq(items) = v else {
602        return Err(E::custom("a pattern must be an array"));
603    };
604    let mut p = Pattern::with_capacity(items.len());
605    for item in items {
606        let part = match item {
607            Value::Str(s) => PatternPart::Text(s),
608            Value::Map(m) => {
609                let is_markup = m
610                    .iter()
611                    .any(|(k, v)| k == "type" && matches!(v, Value::Str(t) if t == "markup"));
612                if is_markup {
613                    PatternPart::Markup(markup(Value::Map(m))?)
614                } else {
615                    PatternPart::Expression(expression(Value::Map(m))?)
616                }
617            }
618            _ => return Err(E::custom("a pattern element must be a string or an object")),
619        };
620        p.push(part);
621    }
622    Ok(p)
623}
624
625enum Arg<'de> {
626    Literal(Literal<'de>),
627    Variable(VariableRef<'de>),
628}
629
630fn arg<E: de::Error>(v: Value<'_>) -> Result<Arg<'_>, E> {
631    let mut o = Obj::new(v, "a literal or variable must be an object")?;
632    match &*o.tag::<E>()? {
633        "literal" => Ok(Arg::Literal(Literal {
634            value: o.string::<E>("value", "a literal needs a string `value`")?,
635        })),
636        "variable" => Ok(Arg::Variable(VariableRef {
637            name: o.string::<E>("name", "a variable needs a string `name`")?,
638        })),
639        _ => Err(E::custom("expected `type` \"literal\" or \"variable\"")),
640    }
641}
642
643fn variable_ref<E: de::Error>(v: Value<'_>) -> Result<VariableRef<'_>, E> {
644    match arg(v)? {
645        Arg::Variable(v) => Ok(v),
646        Arg::Literal(_) => Err(E::custom("a selector must be a variable")),
647    }
648}
649
650fn literal<E: de::Error>(v: Value<'_>) -> Result<Literal<'_>, E> {
651    match arg(v)? {
652        Arg::Literal(l) => Ok(l),
653        Arg::Variable(_) => Err(E::custom("expected a literal")),
654    }
655}
656
657fn expression<E: de::Error>(v: Value<'_>) -> Result<Expression<'_>, E> {
658    let mut o = Obj::new(v, "an expression must be an object")?;
659    o.expect_tag::<E>(
660        "expression",
661        "an expression's `type` must be \"expression\"",
662    )?;
663    let arg = o.take("arg").map(arg::<E>).transpose()?;
664    let function = o.take("function").map(function_ref::<E>).transpose()?;
665    let attributes =
666        attributes::<E>(o.map_or_empty::<E>("attributes", "`attributes` must be an object")?)?;
667    Ok(match (arg, function) {
668        (Some(Arg::Literal(arg)), function) => Expression::Literal(LiteralExpression {
669            arg,
670            function,
671            attributes,
672        }),
673        (Some(Arg::Variable(arg)), function) => Expression::Variable(VariableExpression {
674            arg,
675            function,
676            attributes,
677        }),
678        (None, Some(function)) => Expression::Function(FunctionExpression {
679            function,
680            attributes,
681        }),
682        (None, None) => return Err(E::custom("an expression needs an `arg` or a `function`")),
683    })
684}
685
686fn function_ref<E: de::Error>(v: Value<'_>) -> Result<FunctionRef<'_>, E> {
687    let mut o = Obj::new(v, "a function must be an object")?;
688    o.expect_tag::<E>("function", "a function's `type` must be \"function\"")?;
689    let name = o.string::<E>("name", "a function needs a string `name`")?;
690    let options = options::<E>(o.map_or_empty::<E>("options", "`options` must be an object")?)?;
691    Ok(FunctionRef { name, options })
692}
693
694fn options<E: de::Error>(members: Members<'_>) -> Result<Options<'_>, E> {
695    let mut out = Options::with_capacity(members.len());
696    for (k, v) in members {
697        let value = match arg(v)? {
698            Arg::Literal(l) => OptionValue::Literal(l),
699            Arg::Variable(v) => OptionValue::Variable(v),
700        };
701        out.push(k, value);
702    }
703    Ok(out)
704}
705
706fn attributes<E: de::Error>(members: Members<'_>) -> Result<Attributes<'_>, E> {
707    let mut out = Attributes::with_capacity(members.len());
708    for (k, v) in members {
709        let value = match v {
710            Value::Bool(true) => None,
711            Value::Map(_) => Some(literal(v)?),
712            _ => {
713                return Err(E::custom(
714                    "an attribute's value must be a literal or `true`",
715                ));
716            }
717        };
718        out.push(k, value);
719    }
720    Ok(out)
721}
722
723fn markup<E: de::Error>(v: Value<'_>) -> Result<Markup<'_>, E> {
724    let mut o = Obj::new(v, "markup must be an object")?;
725    o.expect_tag::<E>("markup", "markup's `type` must be \"markup\"")?;
726    let kind = match &*o.string::<E>("kind", "markup needs a string `kind`")? {
727        "open" => MarkupKind::Open,
728        "standalone" => MarkupKind::Standalone,
729        "close" => MarkupKind::Close,
730        _ => {
731            return Err(E::custom(
732                "markup's `kind` must be open, standalone or close",
733            ));
734        }
735    };
736    let name = o.string::<E>("name", "markup needs a string `name`")?;
737    let options = options::<E>(o.map_or_empty::<E>("options", "`options` must be an object")?)?;
738    let attributes =
739        attributes::<E>(o.map_or_empty::<E>("attributes", "`attributes` must be an object")?)?;
740    Ok(Markup {
741        kind,
742        name,
743        options,
744        attributes,
745    })
746}
747
748macro_rules! deserialize_via {
749    ($ty:ident, $f:ident) => {
750        impl<'de: 'a, 'a> Deserialize<'de> for $ty<'a> {
751            fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
752                $f(Value::deserialize(d)?)
753            }
754        }
755    };
756}
757
758deserialize_via!(Message, message);
759deserialize_via!(Declaration, declaration);
760deserialize_via!(Variant, variant);
761deserialize_via!(Key, key);
762deserialize_via!(Pattern, pattern);
763deserialize_via!(Expression, expression);
764deserialize_via!(FunctionRef, function_ref);
765deserialize_via!(Markup, markup);
766deserialize_via!(Literal, literal);
767deserialize_via!(VariableRef, variable_ref);