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), 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 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); impl 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 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 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 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 (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 (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 (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 (_, 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 pub fn value_ty(&self) -> Type {
307 match *self {
308 IDLValue::Null => TypeInner::Null,
309 IDLValue::Bool(_) => TypeInner::Bool,
310 IDLValue::Number(_) => TypeInner::Int, 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 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#[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 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 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}