essential_asm_spec/
de.rs

1//! Custom deserialize implementations for enums and the `Tree` type.
2
3use crate::{Node, StackOut, Tree};
4use serde::{Deserialize, Deserializer};
5use std::collections::BTreeMap;
6
7impl<'de> Deserialize<'de> for Tree {
8    fn deserialize<D>(d: D) -> Result<Self, D::Error>
9    where
10        D: Deserializer<'de>,
11    {
12        // Deserialize into the expected mapping, then convert the map to an
13        // ordered, sorted list based on opcode.
14        let map = BTreeMap::<String, Node>::deserialize(d)?;
15        let mut vec: Vec<_> = map.into_iter().collect();
16        vec.sort_by_key(|(_name, node)| node.opcode());
17        Ok(Self(vec))
18    }
19}
20
21impl<'de> Deserialize<'de> for Node {
22    fn deserialize<D>(d: D) -> Result<Self, D::Error>
23    where
24        D: Deserializer<'de>,
25    {
26        let mapping = serde_yaml::Mapping::deserialize(d)?;
27        let node = if mapping.contains_key("opcode") {
28            let value = serde_yaml::Value::Mapping(mapping);
29            let op = serde_yaml::from_value(value).map_err(serde::de::Error::custom)?;
30            Node::Op(op)
31        } else {
32            let value = serde_yaml::Value::Mapping(mapping);
33            let group = serde_yaml::from_value(value).map_err(serde::de::Error::custom)?;
34            Node::Group(group)
35        };
36        Ok(node)
37    }
38}
39
40impl<'de> Deserialize<'de> for StackOut {
41    fn deserialize<D>(d: D) -> Result<Self, D::Error>
42    where
43        D: Deserializer<'de>,
44    {
45        let value = serde_yaml::Value::deserialize(d)?;
46        let stack_out = match &value {
47            serde_yaml::Value::Sequence(_) => {
48                let fixed = serde_yaml::from_value(value).map_err(serde::de::Error::custom)?;
49                StackOut::Fixed(fixed)
50            }
51            _ => {
52                let dynamic = serde_yaml::from_value(value).map_err(serde::de::Error::custom)?;
53                StackOut::Dynamic(dynamic)
54            }
55        };
56        Ok(stack_out)
57    }
58}