Skip to main content

wit_parser/
serde_.rs

1use crate::{IndexMap, Span, Type};
2use alloc::string::{String, ToString};
3use id_arena::{Arena, Id};
4use semver::Version;
5use serde::ser::{SerializeMap, SerializeSeq, Serializer};
6use serde::{Deserialize, Serialize, de::Error};
7
8pub fn serialize_none<S>(serializer: S) -> Result<S::Ok, S::Error>
9where
10    S: Serializer,
11{
12    serializer.serialize_none()
13}
14
15pub fn serialize_arena<T, S>(arena: &Arena<T>, serializer: S) -> Result<S::Ok, S::Error>
16where
17    T: Serialize,
18    S: Serializer,
19{
20    let mut seq = serializer.serialize_seq(Some(arena.len()))?;
21    for (_, item) in arena.iter() {
22        seq.serialize_element(&item)?;
23    }
24    seq.end()
25}
26
27pub fn serialize_id<T, S>(id: &Id<T>, serializer: S) -> Result<S::Ok, S::Error>
28where
29    S: Serializer,
30{
31    serializer.serialize_u64(id.index() as u64)
32}
33
34/// Variant-level serialize_with for struct variants that have an id and a
35/// skipped span, preserving the old newtype serialization format.
36pub fn serialize_id_ignore_span<T, S>(
37    id: &Id<T>,
38    _span: &Span,
39    serializer: S,
40) -> Result<S::Ok, S::Error>
41where
42    S: Serializer,
43{
44    serialize_id(id, serializer)
45}
46
47pub fn serialize_optional_id<T, S>(id: &Option<Id<T>>, serializer: S) -> Result<S::Ok, S::Error>
48where
49    S: Serializer,
50{
51    match id {
52        Some(id) => serialize_id(&id, serializer),
53        None => serializer.serialize_none(),
54    }
55}
56
57pub fn serialize_id_map<K, T, S>(map: &IndexMap<K, Id<T>>, serializer: S) -> Result<S::Ok, S::Error>
58where
59    K: Serialize,
60    S: Serializer,
61{
62    let mut s = serializer.serialize_map(Some(map.len()))?;
63    for (key, id) in map.iter() {
64        s.serialize_entry(key, &(id.index() as u64))?;
65    }
66    s.end()
67}
68
69impl Serialize for Type {
70    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
71    where
72        S: Serializer,
73    {
74        match self {
75            Type::Bool => serializer.serialize_str("bool"),
76            Type::U8 => serializer.serialize_str("u8"),
77            Type::U16 => serializer.serialize_str("u16"),
78            Type::U32 => serializer.serialize_str("u32"),
79            Type::U64 => serializer.serialize_str("u64"),
80            Type::S8 => serializer.serialize_str("s8"),
81            Type::S16 => serializer.serialize_str("s16"),
82            Type::S32 => serializer.serialize_str("s32"),
83            Type::S64 => serializer.serialize_str("s64"),
84            Type::F32 => serializer.serialize_str("f32"),
85            Type::F64 => serializer.serialize_str("f64"),
86            Type::Char => serializer.serialize_str("char"),
87            Type::String => serializer.serialize_str("string"),
88            Type::ErrorContext => serializer.serialize_str("error-context"),
89            Type::Id(type_id) => serializer.serialize_u64(type_id.index() as u64),
90        }
91    }
92}
93
94pub fn serialize_version<S>(version: &Version, serializer: S) -> Result<S::Ok, S::Error>
95where
96    S: Serializer,
97{
98    version.to_string().serialize(serializer)
99}
100
101pub fn deserialize_version<'de, D>(deserializer: D) -> Result<Version, D::Error>
102where
103    D: serde::de::Deserializer<'de>,
104{
105    let version: String = String::deserialize(deserializer)?;
106    version.parse().map_err(|e| D::Error::custom(e))
107}
108
109pub fn serialize_optional_version<S>(
110    version: &Option<Version>,
111    serializer: S,
112) -> Result<S::Ok, S::Error>
113where
114    S: Serializer,
115{
116    version
117        .as_ref()
118        .map(|s| s.to_string())
119        .serialize(serializer)
120}
121
122pub fn deserialize_optional_version<'de, D>(deserializer: D) -> Result<Option<Version>, D::Error>
123where
124    D: serde::de::Deserializer<'de>,
125{
126    match <Option<String>>::deserialize(deserializer)? {
127        Some(version) => Ok(Some(version.parse().map_err(|e| D::Error::custom(e))?)),
128        None => Ok(None),
129    }
130}