candid/types/
value.rs

1use crate::types::number::{Int, Nat};
2use crate::types::{Field, Label, Type, TypeEnv, TypeInner};
3use crate::{CandidType, DecoderConfig, Error, Result};
4use serde::de;
5use serde::de::{Deserialize, Visitor};
6use std::collections::HashMap;
7use std::fmt;
8use std::ops::Deref;
9
10#[derive(PartialEq, Clone)]
11pub enum IDLValue {
12    Bool(bool),
13    Null,
14    Text(String),
15    Number(String), // Undetermined number type
16    Float64(f64),
17    Opt(Box<IDLValue>),
18    Vec(Vec<IDLValue>),
19    Record(Vec<IDLField>),
20    Variant(VariantValue),
21    Blob(Vec<u8>),
22    Principal(crate::Principal),
23    Service(crate::Principal),
24    Func(crate::Principal, String),
25    // The following values can only be generated with type annotation
26    None,
27    Int(Int),
28    Nat(Nat),
29    Nat8(u8),
30    Nat16(u16),
31    Nat32(u32),
32    Nat64(u64),
33    Int8(i8),
34    Int16(i16),
35    Int32(i32),
36    Int64(i64),
37    Float32(f32),
38    Reserved,
39}
40
41#[derive(Clone)]
42pub struct VariantValue(pub Box<IDLField>, pub u64); // u64 represents the index from the type, defaults to 0 when parsing, only used for serialization
43impl PartialEq for VariantValue {
44    fn eq(&self, other: &Self) -> bool {
45        self.0 == other.0
46    }
47}
48
49#[derive(PartialEq, Clone)]
50pub struct IDLField {
51    pub id: Label,
52    pub val: IDLValue,
53}
54
55#[derive(PartialEq, Clone)]
56pub struct IDLArgs {
57    pub args: Vec<IDLValue>,
58}
59
60impl IDLArgs {
61    pub fn new(args: &[IDLValue]) -> Self {
62        IDLArgs {
63            args: args.to_owned(),
64        }
65    }
66    pub fn annotate_types(self, from_parser: bool, env: &TypeEnv, types: &[Type]) -> Result<Self> {
67        let mut args = Vec::new();
68        for (v, ty) in self.args.iter().zip(types.iter()) {
69            let v = v.annotate_type(from_parser, env, ty)?;
70            args.push(v);
71        }
72        for ty in types[self.args.len()..].iter() {
73            let v = match env.trace_type(ty)?.as_ref() {
74                TypeInner::Null => IDLValue::Null,
75                TypeInner::Reserved => IDLValue::Reserved,
76                TypeInner::Opt(_) => IDLValue::None,
77                _ => return Err(Error::msg(format!("Omitted values cannot be of type {ty}"))),
78            };
79            args.push(v);
80        }
81        Ok(IDLArgs { args })
82    }
83    pub fn get_types(&self) -> Vec<Type> {
84        self.args.iter().map(|v| v.value_ty()).collect()
85    }
86    /// Encode IDLArgs with the given types. Note that this is not equivalent to
87    /// `idl_args.annotate_types(true, env, types).to_bytes()` for recursive types.
88    pub fn to_bytes_with_types(&self, env: &TypeEnv, types: &[Type]) -> Result<Vec<u8>> {
89        if types.len() > self.args.len() {
90            return Err(Error::msg("wrong number of argument values"));
91        }
92        let mut idl = crate::ser::IDLBuilder::new();
93        let empty_env = TypeEnv::new();
94        for (i, (v, ty)) in self.args.iter().zip(types.iter()).enumerate() {
95            if i == 0 {
96                // env gets merged into the builder state, we only need to pass in env once.
97                idl.value_arg_with_type(v, env, ty)?;
98            } else {
99                idl.value_arg_with_type(v, &empty_env, ty)?;
100            }
101        }
102        idl.serialize_to_vec()
103    }
104    pub fn to_bytes(&self) -> Result<Vec<u8>> {
105        let mut idl = crate::ser::IDLBuilder::new();
106        for v in self.args.iter() {
107            idl.value_arg(v)?;
108        }
109        idl.serialize_to_vec()
110    }
111    pub fn from_bytes_with_types(bytes: &[u8], env: &TypeEnv, types: &[Type]) -> Result<Self> {
112        let mut de = crate::de::IDLDeserialize::new(bytes)?;
113        let mut args = Vec::new();
114        for ty in types.iter() {
115            let v = de.get_value_with_type(env, ty)?;
116            args.push(v);
117        }
118        de.done()?;
119        Ok(IDLArgs { args })
120    }
121    pub fn from_bytes_with_types_with_config(
122        bytes: &[u8],
123        env: &TypeEnv,
124        types: &[Type],
125        config: &DecoderConfig,
126    ) -> Result<Self> {
127        let mut de = crate::de::IDLDeserialize::new_with_config(bytes, config)?;
128        let mut args = Vec::new();
129        for ty in types.iter() {
130            let v = de.get_value_with_type(env, ty)?;
131            args.push(v);
132        }
133        de.done()?;
134        Ok(IDLArgs { args })
135    }
136    pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
137        let mut de = crate::de::IDLDeserialize::new(bytes)?;
138        let mut args = Vec::new();
139        while !de.is_done() {
140            let v = de.get_value::<IDLValue>()?;
141            args.push(v);
142        }
143        de.done()?;
144        Ok(IDLArgs { args })
145    }
146    pub fn from_bytes_with_config(bytes: &[u8], config: &DecoderConfig) -> Result<Self> {
147        let mut de = crate::de::IDLDeserialize::new_with_config(bytes, config)?;
148        let mut args = Vec::new();
149        while !de.is_done() {
150            let v = de.get_value::<IDLValue>()?;
151            args.push(v);
152        }
153        de.done()?;
154        Ok(IDLArgs { args })
155    }
156}
157
158impl IDLValue {
159    /// Anotate `IDLValue` with the given type, allowing subtyping. If `IDLValue` is parsed from
160    /// string, we need to set `from_parser` to true to enable converting numbers to the expected
161    /// types, and disable the opt rules.
162    pub fn annotate_type(&self, from_parser: bool, env: &TypeEnv, t: &Type) -> Result<Self> {
163        Ok(match (self, t.as_ref()) {
164            (_, TypeInner::Var(id)) => {
165                let ty = env.rec_find_type(id)?;
166                self.annotate_type(from_parser, env, ty)?
167            }
168            (_, TypeInner::Knot(ref id)) => {
169                let ty = crate::types::internal::find_type(id).unwrap();
170                self.annotate_type(from_parser, env, &ty)?
171            }
172            (_, TypeInner::Reserved) => IDLValue::Reserved,
173            (IDLValue::Float64(n), TypeInner::Float32) if from_parser => {
174                IDLValue::Float32(*n as f32)
175            }
176            (IDLValue::Null, TypeInner::Null) => IDLValue::Null,
177            (IDLValue::Bool(b), TypeInner::Bool) => IDLValue::Bool(*b),
178            (IDLValue::Nat(n), TypeInner::Nat) => IDLValue::Nat(n.clone()),
179            (IDLValue::Int(i), TypeInner::Int) => IDLValue::Int(i.clone()),
180            (IDLValue::Nat(n), TypeInner::Int) => IDLValue::Int(n.clone().into()),
181            (IDLValue::Nat8(n), TypeInner::Nat8) => IDLValue::Nat8(*n),
182            (IDLValue::Nat16(n), TypeInner::Nat16) => IDLValue::Nat16(*n),
183            (IDLValue::Nat32(n), TypeInner::Nat32) => IDLValue::Nat32(*n),
184            (IDLValue::Nat64(n), TypeInner::Nat64) => IDLValue::Nat64(*n),
185            (IDLValue::Int8(n), TypeInner::Int8) => IDLValue::Int8(*n),
186            (IDLValue::Int16(n), TypeInner::Int16) => IDLValue::Int16(*n),
187            (IDLValue::Int32(n), TypeInner::Int32) => IDLValue::Int32(*n),
188            (IDLValue::Int64(n), TypeInner::Int64) => IDLValue::Int64(*n),
189            (IDLValue::Float64(n), TypeInner::Float64) => IDLValue::Float64(*n),
190            (IDLValue::Float32(n), TypeInner::Float32) => IDLValue::Float32(*n),
191            (IDLValue::Text(s), TypeInner::Text) => IDLValue::Text(s.to_owned()),
192            // opt parsing. NB: Always succeeds!
193            (IDLValue::Null, TypeInner::Opt(_)) => IDLValue::None,
194            (IDLValue::Reserved, TypeInner::Opt(_)) => IDLValue::None,
195            (IDLValue::None, TypeInner::Opt(_)) => IDLValue::None,
196            (IDLValue::Opt(v), TypeInner::Opt(ty)) if from_parser => {
197                IDLValue::Opt(Box::new(v.annotate_type(from_parser, env, ty)?))
198            }
199            // liberal decoding of optionals
200            (IDLValue::Opt(v), TypeInner::Opt(ty)) if !from_parser => v
201                .annotate_type(from_parser, env, ty)
202                .map(|v| IDLValue::Opt(Box::new(v)))
203                .unwrap_or(IDLValue::None),
204            // try consituent type
205            (v, TypeInner::Opt(ty))
206                if !from_parser
207                    && !matches!(
208                        env.trace_type(ty)?.as_ref(),
209                        TypeInner::Null | TypeInner::Reserved | TypeInner::Opt(_)
210                    ) =>
211            {
212                v.annotate_type(from_parser, env, ty)
213                    .map(|v| IDLValue::Opt(Box::new(v)))
214                    .unwrap_or(IDLValue::None)
215            }
216            // fallback
217            (_, TypeInner::Opt(_)) if !from_parser => IDLValue::None,
218            (IDLValue::Blob(blob), ty) if ty.is_blob(env) => IDLValue::Blob(blob.to_vec()),
219            (IDLValue::Vec(vec), ty) if ty.is_blob(env) => {
220                let mut blob = Vec::with_capacity(vec.len());
221                for e in vec.iter() {
222                    match e {
223                        IDLValue::Nat8(n) => blob.push(*n),
224                        IDLValue::Number(n) => blob.push(n.parse::<u8>()?),
225                        _ => {
226                            return Err(Error::msg(format!(
227                                "type mismatch: {e} cannot be of type nat8"
228                            )))
229                        }
230                    }
231                }
232                IDLValue::Blob(blob)
233            }
234            (IDLValue::Vec(vec), TypeInner::Vec(ty)) => {
235                let mut res = Vec::with_capacity(vec.len());
236                for e in vec.iter() {
237                    let v = e.annotate_type(from_parser, env, ty)?;
238                    res.push(v);
239                }
240                IDLValue::Vec(res)
241            }
242            (IDLValue::Record(vec), TypeInner::Record(fs)) => {
243                let fields: HashMap<_, _> =
244                    vec.iter().map(|IDLField { id, val }| (id, val)).collect();
245                let mut res = Vec::new();
246                for Field { id, ty } in fs.iter() {
247                    let val = fields
248                        .get(id.as_ref())
249                        .cloned()
250                        .or_else(|| match env.trace_type(ty).unwrap().as_ref() {
251                            TypeInner::Null => Some(&IDLValue::Null),
252                            TypeInner::Opt(_) => Some(&IDLValue::None),
253                            TypeInner::Reserved => Some(&IDLValue::Reserved),
254                            _ => None,
255                        })
256                        .ok_or_else(|| Error::msg(format!("record field {id} not found")))?;
257                    let val = val.annotate_type(from_parser, env, ty)?;
258                    res.push(IDLField {
259                        id: id.as_ref().clone(),
260                        val,
261                    });
262                }
263                IDLValue::Record(res)
264            }
265            (IDLValue::Variant(v), TypeInner::Variant(fs)) => {
266                for (i, f) in fs.iter().enumerate() {
267                    if v.0.id == *f.id {
268                        let val = v.0.val.annotate_type(from_parser, env, &f.ty)?;
269                        let field = IDLField {
270                            id: f.id.as_ref().clone(),
271                            val,
272                        };
273                        return Ok(IDLValue::Variant(VariantValue(Box::new(field), i as u64)));
274                    }
275                }
276                return Err(Error::msg(format!("variant field {} not found", v.0.id)));
277            }
278            (IDLValue::Principal(id), TypeInner::Principal) => IDLValue::Principal(*id),
279            (IDLValue::Service(_), TypeInner::Service(_)) => self.clone(),
280            (IDLValue::Func(_, _), TypeInner::Func(_)) => self.clone(),
281            (IDLValue::Number(str), _) if from_parser => match t.as_ref() {
282                TypeInner::Int => IDLValue::Int(str.parse::<Int>()?),
283                TypeInner::Nat => IDLValue::Nat(str.parse::<Nat>()?),
284                TypeInner::Nat8 => IDLValue::Nat8(str.parse::<u8>()?),
285                TypeInner::Nat16 => IDLValue::Nat16(str.parse::<u16>()?),
286                TypeInner::Nat32 => IDLValue::Nat32(str.parse::<u32>()?),
287                TypeInner::Nat64 => IDLValue::Nat64(str.parse::<u64>()?),
288                TypeInner::Int8 => IDLValue::Int8(str.parse::<i8>()?),
289                TypeInner::Int16 => IDLValue::Int16(str.parse::<i16>()?),
290                TypeInner::Int32 => IDLValue::Int32(str.parse::<i32>()?),
291                TypeInner::Int64 => IDLValue::Int64(str.parse::<i64>()?),
292                _ => {
293                    return Err(Error::msg(format!(
294                        "type mismatch: {self} can not be of type {t}"
295                    )))
296                }
297            },
298            _ => {
299                return Err(Error::msg(format!(
300                    "type mismatch: {self} cannot be of type {t}"
301                )))
302            }
303        })
304    }
305    // This will only be called when the type is not provided
306    pub fn value_ty(&self) -> Type {
307        match *self {
308            IDLValue::Null => TypeInner::Null,
309            IDLValue::Bool(_) => TypeInner::Bool,
310            IDLValue::Number(_) => TypeInner::Int, // Number defaults to Int
311            IDLValue::Int(_) => TypeInner::Int,
312            IDLValue::Nat(_) => TypeInner::Nat,
313            IDLValue::Nat8(_) => TypeInner::Nat8,
314            IDLValue::Nat16(_) => TypeInner::Nat16,
315            IDLValue::Nat32(_) => TypeInner::Nat32,
316            IDLValue::Nat64(_) => TypeInner::Nat64,
317            IDLValue::Int8(_) => TypeInner::Int8,
318            IDLValue::Int16(_) => TypeInner::Int16,
319            IDLValue::Int32(_) => TypeInner::Int32,
320            IDLValue::Int64(_) => TypeInner::Int64,
321            IDLValue::Float32(_) => TypeInner::Float32,
322            IDLValue::Float64(_) => TypeInner::Float64,
323            IDLValue::Text(_) => TypeInner::Text,
324            IDLValue::None => TypeInner::Opt(TypeInner::Empty.into()),
325            IDLValue::Reserved => TypeInner::Reserved,
326            IDLValue::Opt(ref v) => {
327                let t = v.deref().value_ty();
328                TypeInner::Opt(t)
329            }
330            IDLValue::Blob(_) => TypeInner::Vec(TypeInner::Nat8.into()),
331            IDLValue::Vec(ref vec) => {
332                let t = if vec.is_empty() {
333                    TypeInner::Empty.into()
334                } else {
335                    vec[0].value_ty()
336                };
337                TypeInner::Vec(t)
338            }
339            IDLValue::Record(ref vec) => {
340                let fs: Vec<_> = vec
341                    .iter()
342                    .map(|IDLField { id, val }| Field {
343                        id: id.clone().into(),
344                        ty: val.value_ty(),
345                    })
346                    .collect();
347                TypeInner::Record(fs)
348            }
349            IDLValue::Variant(ref v) => {
350                let f = Field {
351                    id: v.0.id.clone().into(),
352                    ty: v.0.val.value_ty(),
353                };
354                TypeInner::Variant(vec![f])
355            }
356            IDLValue::Principal(_) => TypeInner::Principal,
357            IDLValue::Service(_) => TypeInner::Service(Vec::new()),
358            IDLValue::Func(_, _) => {
359                let f = crate::types::Function {
360                    modes: Vec::new(),
361                    args: Vec::new(),
362                    rets: Vec::new(),
363                };
364                TypeInner::Func(f)
365            }
366        }
367        .into()
368    }
369
370    /// Converts data that implements [`CandidType`] into an [`IDLValue`].
371    ///
372    /// # Example: Convert data to candid text format
373    /// ```
374    /// # use candid::{CandidType, IDLValue};
375    /// #[derive(CandidType)]
376    /// struct MyStruct {
377    ///    a: u8,
378    ///   b: String,
379    /// }
380    /// let my_struct = MyStruct { a: 42, b: "hello".to_string() };
381    /// let idl_value = IDLValue::try_from_candid_type(&my_struct).unwrap();
382    /// let expected_text = "record { a = 42 : nat8; b = \"hello\" }";
383    /// let actual_text = idl_value.to_string();
384    /// assert_eq!(expected_text, actual_text);
385    /// ```
386    pub fn try_from_candid_type<T>(data: &T) -> Result<Self>
387    where
388        T: CandidType,
389    {
390        use crate::Encode;
391        let blob = Encode!(data)?;
392        let args = IDLArgs::from_bytes_with_types(&blob, &TypeEnv::default(), &[T::ty()])?;
393        Ok(args.args[0].clone())
394    }
395}
396
397impl crate::CandidType for IDLValue {
398    fn ty() -> Type {
399        TypeInner::Unknown.into()
400    }
401    fn id() -> crate::types::TypeId {
402        unreachable!();
403    }
404    fn _ty() -> Type {
405        TypeInner::Unknown.into()
406    }
407    fn idl_serialize<S>(&self, serializer: S) -> std::result::Result<(), S::Error>
408    where
409        S: crate::types::Serializer,
410    {
411        use crate::types::Compound;
412        match *self {
413            IDLValue::Null => serializer.serialize_null(()),
414            IDLValue::Bool(b) => serializer.serialize_bool(b),
415            IDLValue::Number(ref str) => {
416                let v = str.parse::<Int>().map_err(serde::ser::Error::custom)?;
417                serializer.serialize_int(&v)
418            }
419            IDLValue::Int(ref i) => serializer.serialize_int(i),
420            IDLValue::Nat(ref n) => serializer.serialize_nat(n),
421            IDLValue::Nat8(n) => serializer.serialize_nat8(n),
422            IDLValue::Nat16(n) => serializer.serialize_nat16(n),
423            IDLValue::Nat32(n) => serializer.serialize_nat32(n),
424            IDLValue::Nat64(n) => serializer.serialize_nat64(n),
425            IDLValue::Int8(n) => serializer.serialize_int8(n),
426            IDLValue::Int16(n) => serializer.serialize_int16(n),
427            IDLValue::Int32(n) => serializer.serialize_int32(n),
428            IDLValue::Int64(n) => serializer.serialize_int64(n),
429            IDLValue::Float32(f) => serializer.serialize_float32(f),
430            IDLValue::Float64(f) => serializer.serialize_float64(f),
431            IDLValue::Text(ref s) => serializer.serialize_text(s),
432            IDLValue::None => serializer.serialize_option::<Option<String>>(None),
433            IDLValue::Opt(ref v) => serializer.serialize_option(Some(v.deref())),
434            IDLValue::Vec(ref vec) => {
435                let mut ser = serializer.serialize_vec(vec.len())?;
436                for e in vec.iter() {
437                    ser.serialize_element(&e)?;
438                }
439                Ok(())
440            }
441            IDLValue::Blob(ref blob) => serializer.serialize_blob(blob),
442            IDLValue::Record(ref vec) => {
443                let mut ser = serializer.serialize_struct()?;
444                for f in vec.iter() {
445                    ser.serialize_element(&f.val)?;
446                }
447                Ok(())
448            }
449            IDLValue::Variant(ref v) => {
450                let mut ser = serializer.serialize_variant(v.1)?;
451                ser.serialize_element(&v.0.val)?;
452                Ok(())
453            }
454            IDLValue::Principal(ref id) => serializer.serialize_principal(id.as_slice()),
455            IDLValue::Service(ref id) => serializer.serialize_principal(id.as_slice()),
456            IDLValue::Func(ref id, ref meth) => serializer.serialize_function(id.as_slice(), meth),
457            IDLValue::Reserved => serializer.serialize_null(()),
458        }
459    }
460}
461
462type DResult<E> = std::result::Result<IDLValue, E>;
463
464macro_rules! visit_prim {
465    ($name:ident, $ty:ty) => {
466        paste::item! {
467            fn [<visit_ $ty>]<E>(self, value: $ty) -> DResult<E> {
468                Ok(IDLValue::$name(value))
469            }
470        }
471    };
472}
473
474/// A [`Visitor`] to extract [`IDLValue`]s.
475#[derive(Copy, Clone)]
476pub struct IDLValueVisitor;
477
478impl<'de> Visitor<'de> for IDLValueVisitor {
479    type Value = IDLValue;
480    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
481        formatter.write_str("any valid Candid value")
482    }
483    visit_prim!(Bool, bool);
484    visit_prim!(Nat8, u8);
485    visit_prim!(Nat16, u16);
486    visit_prim!(Nat32, u32);
487    visit_prim!(Nat64, u64);
488    visit_prim!(Int8, i8);
489    visit_prim!(Int16, i16);
490    visit_prim!(Int32, i32);
491    visit_prim!(Int64, i64);
492    visit_prim!(Float32, f32);
493    visit_prim!(Float64, f64);
494    // Deserialize Candid specific types: Bignumber, principal, reversed, service, function, blob
495    fn visit_byte_buf<E: de::Error>(self, value: Vec<u8>) -> DResult<E> {
496        let (tag, mut bytes) = value.split_at(1);
497        match tag[0] {
498            0u8 => {
499                let v = Int(num_bigint::BigInt::from_signed_bytes_le(bytes));
500                Ok(IDLValue::Int(v))
501            }
502            1u8 => {
503                let v = Nat(num_bigint::BigUint::from_bytes_le(bytes));
504                Ok(IDLValue::Nat(v))
505            }
506            2u8 => {
507                let v = crate::Principal::try_from(bytes).map_err(E::custom)?;
508                Ok(IDLValue::Principal(v))
509            }
510            3u8 => Ok(IDLValue::Reserved),
511            4u8 => {
512                let v = crate::Principal::try_from(bytes).map_err(E::custom)?;
513                Ok(IDLValue::Service(v))
514            }
515            5u8 => {
516                use std::io::Read;
517                let len = leb128::read::unsigned(&mut bytes).map_err(E::custom)? as usize;
518                let mut buf = vec![0; len];
519                bytes.read_exact(&mut buf).map_err(E::custom)?;
520                let meth = String::from_utf8(buf).map_err(E::custom)?;
521                let id = crate::Principal::try_from(bytes).map_err(E::custom)?;
522                Ok(IDLValue::Func(id, meth))
523            }
524            6u8 => Ok(IDLValue::Blob(bytes.to_vec())),
525            _ => Err(de::Error::custom("unknown tag in visit_byte_buf")),
526        }
527    }
528    fn visit_string<E>(self, value: String) -> DResult<E> {
529        Ok(IDLValue::Text(value))
530    }
531    fn visit_str<E>(self, value: &str) -> DResult<E>
532    where
533        E: serde::de::Error,
534    {
535        self.visit_string(String::from(value))
536    }
537    fn visit_none<E>(self) -> DResult<E> {
538        Ok(IDLValue::None)
539    }
540    fn visit_some<D>(self, deserializer: D) -> DResult<D::Error>
541    where
542        D: serde::Deserializer<'de>,
543    {
544        let v = Deserialize::deserialize(deserializer)?;
545        Ok(IDLValue::Opt(Box::new(v)))
546    }
547    fn visit_unit<E>(self) -> DResult<E> {
548        Ok(IDLValue::Null)
549    }
550    fn visit_seq<V>(self, mut visitor: V) -> DResult<V::Error>
551    where
552        V: de::SeqAccess<'de>,
553    {
554        let mut vec = Vec::new();
555        while let Some(elem) = visitor.next_element()? {
556            vec.push(elem);
557        }
558        Ok(IDLValue::Vec(vec))
559    }
560    fn visit_map<V>(self, mut visitor: V) -> DResult<V::Error>
561    where
562        V: de::MapAccess<'de>,
563    {
564        let mut vec = Vec::new();
565        while let Some((key, value)) = visitor.next_entry()? {
566            let id = match key {
567                IDLValue::Nat32(hash) => Label::Id(hash),
568                IDLValue::Text(name) if name == "_" => continue,
569                IDLValue::Text(name) => Label::Named(name),
570                _ => unreachable!(),
571            };
572            let f = IDLField { id, val: value };
573            vec.push(f);
574        }
575        Ok(IDLValue::Record(vec))
576    }
577    fn visit_enum<V>(self, data: V) -> DResult<V::Error>
578    where
579        V: de::EnumAccess<'de>,
580    {
581        use serde::de::VariantAccess;
582        let (variant, visitor) = data.variant::<IDLValue>()?;
583        if let IDLValue::Text(v) = variant {
584            let v: Vec<_> = v.split(',').collect();
585            let (id, style) = match v.as_slice() {
586                [name, "name", style] => (Label::Named(name.to_string()), style),
587                [hash, "id", style] => (Label::Id(hash.parse::<u32>().unwrap()), style),
588                _ => unreachable!(),
589            };
590            let val = match *style {
591                "unit" => {
592                    visitor.unit_variant()?;
593                    IDLValue::Null
594                }
595                "struct" => visitor.struct_variant(&[], self)?,
596                "newtype" => visitor.newtype_variant()?,
597                _ => unreachable!(),
598            };
599            let f = IDLField { id, val };
600            // Deserialized variant always has 0 index to ensure untyped
601            // serialization is correct.
602            Ok(IDLValue::Variant(VariantValue(Box::new(f), 0)))
603        } else {
604            unreachable!()
605        }
606    }
607}
608
609impl<'de> Deserialize<'de> for IDLValue {
610    fn deserialize<D>(deserializer: D) -> DResult<D::Error>
611    where
612        D: serde::Deserializer<'de>,
613    {
614        deserializer.deserialize_any(IDLValueVisitor)
615    }
616}