Skip to main content

concordium_contracts_common/
schema_json.rs

1use crate::{constants::*, schema::*, *};
2use core::fmt::Display;
3use num_bigint::{BigInt, BigUint};
4use num_traits::Zero;
5use serde_json::{json, Map, Value};
6use std::convert::{TryFrom, TryInto};
7
8/// Trait which includes implementations for unwrapping recursive error
9/// structures. Requires that the implementor supplies implementations for
10/// accessing data for individual layers of the nested structure.
11///
12/// This is intended to be private to the module, as it merely serves the
13/// purpose of code de-duplication.
14trait TraceError {
15    /// Returns an error message layer associated with this error, along with a
16    /// reference to the error this error wraps. If this error is not a
17    /// wrapping layer, None is expected to be returned.
18    fn display_layer(&self, verbose: bool) -> (String, Option<&Self>);
19
20    /// Returns a formatted error message for a [`TraceError`].
21    /// It supports printing a verbose form including a more detailed
22    /// description of the error stack, which is returned if `verbose` is
23    /// set to true.
24    fn display_nested(&self, verbose: bool) -> String {
25        let mut out = String::new();
26        let mut current_error = self;
27        let mut is_initial_pass = true;
28
29        loop {
30            let (string, next_error) = current_error.display_layer(verbose);
31            out = if is_initial_pass {
32                is_initial_pass = false;
33                string
34            } else if verbose {
35                format!("{}\n{}", string, out)
36            } else {
37                format!("{} -> {}", out, string)
38            };
39
40            if let Some(next) = next_error {
41                current_error = next;
42            } else {
43                break;
44            }
45        }
46
47        out
48    }
49
50    /// Gets a reference to the error this error wraps. If this error is not a
51    /// wrapping layer, None is expected to be returned.
52    fn get_inner_error(&self) -> Option<&Self>;
53
54    /// Gets the innermost error of a [`TraceError`].
55    fn get_innermost_error(&self) -> &Self {
56        let mut out = self;
57        while let Some(error) = self.get_inner_error() {
58            out = error;
59        }
60        out
61    }
62}
63
64/// Represents errors occurring while serializing data from the schema JSON
65/// format.
66///
67/// # Examples
68///
69/// ## Simple type from invalid JSON value
70/// ```
71/// # use serde_json::json;
72/// # use concordium_contracts_common::schema_json::*;
73/// # use concordium_contracts_common::schema::*;
74/// # use concordium_contracts_common::*;
75/// #
76/// let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
77/// let account = AccountAddress(account_bytes.clone());
78/// let schema = Type::AccountAddress;
79///
80/// // Malformed JSON value due to incorrect account address
81/// let json = json!(format!("{}", &account).get(1..));
82/// let err = schema.serial_value(&json).expect_err("Serializing should fail");
83///
84/// assert!(matches!(err, JsonError::FailedParsingAccountAddress))
85/// ```
86///
87/// ## Complex type from invalid JSON value
88/// ```
89/// # use serde_json::json;
90/// # use concordium_contracts_common::schema_json::*;
91/// # use concordium_contracts_common::schema::*;
92/// # use concordium_contracts_common::*;
93/// #
94/// let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
95/// let account = AccountAddress(account_bytes.clone());
96/// let schema = Type::Struct(Fields::Named(vec![
97///    ("account".into(), Type::AccountAddress),
98///    ("contract".into(), Type::ContractAddress),
99/// ]));
100///
101/// // Malformed JSON value due to incorrect value for "contract" field
102/// let json = json!({ "account": format!("{}", account), "contract": {} });
103/// let err = schema.serial_value(&json).expect_err("Serializing should fail");
104///
105/// assert!(matches!(
106///    err,
107///    JsonError::TraceError {
108///        field,
109///        error,
110///        ..
111///    } if matches!(*error, JsonError::FieldError(_)) && field == "\"contract\""
112/// ));
113/// ```
114#[derive(Debug, thiserror::Error, Clone)]
115pub enum JsonError {
116    FailedWriting,
117    UnsignedIntRequired,
118    SignedIntRequired,
119    FailedParsingAccountAddress,
120    WrongJsonType(String),
121    FieldError(String),
122    EnumError(String),
123    MapError(String),
124    PairError(String),
125    ArrayError(String),
126    ParseError(String),
127    ByteArrayError(String),
128    FromHexError(#[from] hex::FromHexError),
129    TryFromIntError(#[from] core::num::TryFromIntError),
130    ParseIntError(#[from] std::num::ParseIntError),
131    ParseDurationError(#[from] ParseDurationError),
132    ParseTimestampError(#[from] ParseTimestampError),
133    /// Trace leading to the original [`JsonError`].
134    TraceError {
135        field: String,
136        json:  serde_json::Value,
137        error: Box<JsonError>,
138    },
139}
140
141impl Display for JsonError {
142    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
143        match self {
144            JsonError::FailedWriting => write!(f, "Failed writing"),
145            JsonError::UnsignedIntRequired => write!(f, "Unsigned integer required"),
146            JsonError::SignedIntRequired => write!(f, "Signed integer required"),
147            JsonError::FailedParsingAccountAddress => write!(f, "Failed parsing account address"),
148            JsonError::WrongJsonType(s) => write!(f, "{}", s),
149            JsonError::FieldError(s) => write!(f, "{}", s),
150            JsonError::EnumError(s) => write!(f, "{}", s),
151            JsonError::MapError(s) => write!(f, "{}", s),
152            JsonError::PairError(s) => write!(f, "{}", s),
153            JsonError::ArrayError(s) => write!(f, "{}", s),
154            JsonError::ParseError(s) => write!(f, "{}", s),
155            JsonError::ByteArrayError(s) => write!(f, "{}", s),
156            JsonError::FromHexError(e) => write!(f, "{}", e),
157            JsonError::TryFromIntError(e) => write!(f, "{}", e),
158            JsonError::ParseIntError(e) => write!(f, "{}", e),
159            JsonError::ParseDurationError(e) => write!(f, "{}", e),
160            JsonError::ParseTimestampError(e) => write!(f, "{}", e),
161            JsonError::TraceError {
162                ..
163            } => write!(f, "{}", self.display(false)),
164        }
165    }
166}
167
168impl TraceError for JsonError {
169    fn display_layer(&self, verbose: bool) -> (String, Option<&Self>) {
170        if let JsonError::TraceError {
171            error,
172            json,
173            field,
174        } = self
175        {
176            let formatted_json =
177                serde_json::to_string_pretty(json).unwrap_or_else(|_| format!("{}", json));
178            let message = if verbose {
179                format!("In {} of {}", field, formatted_json)
180            } else {
181                field.clone()
182            };
183            return (message, Some(error));
184        }
185
186        let message = format!("{}", self);
187        (message, None)
188    }
189
190    fn get_inner_error(&self) -> Option<&Self> {
191        if let JsonError::TraceError {
192            error,
193            ..
194        } = self
195        {
196            return Some(error);
197        }
198
199        None
200    }
201}
202
203impl JsonError {
204    /// Wraps a [`JsonError`] in a [`JsonError::TraceError`], providing a trace
205    /// to the origin of the error.
206    fn add_trace(self, field: String, json: &serde_json::Value) -> Self {
207        JsonError::TraceError {
208            field,
209            json: json.clone(),
210            error: Box::new(self),
211        }
212    }
213
214    /// Returns a formatted error message for variant. [`JsonError::TraceError`]
215    /// supports printing a verbose form including a more detailed
216    /// description of the error stack, which is returned if `verbose` is
217    /// set to true.
218    ///
219    /// # Examples
220    ///
221    /// ## Display error from list of objects
222    ///
223    /// ```
224    /// # use serde_json::json;
225    /// # use concordium_contracts_common::schema_json::*;
226    /// # use concordium_contracts_common::schema::*;
227    /// # use concordium_contracts_common::*;
228    /// #
229    /// let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
230    /// let account = AccountAddress(account_bytes);
231    /// let object_schema = Type::Struct(Fields::Named(vec![
232    ///    ("account".into(), Type::AccountAddress),
233    ///    ("contract".into(), Type::ContractAddress),
234    /// ]));
235    /// let schema = Type::List(SizeLength::U8, Box::new(object_schema));
236    ///
237    /// // Malformed JSON value due to incorrect value for "contract" field
238    /// let json = json!([{ "account": format!("{}", account), "contract": {} }]);
239    /// let err = schema.serial_value(&json).expect_err("Serializing should fail");
240    ///
241    /// // The error format points to the cause of the error from the root of the JSON.
242    /// # #[rustfmt::skip]
243    /// let expected = r#"0 -> "contract" -> 'index' is required in a Contract address"#.to_string();
244    /// assert_eq!(expected, err.display(false));
245    ///
246    /// // Or if verbose, includes a stacktrace-like format.
247    /// # #[rustfmt::skip]
248    /// let expected_verbose = r#"'index' is required in a Contract address
249    /// In "contract" of {
250    ///   "account": "2wkBET2rRgE8pahuaczxKbmv7ciehqsne57F9gtzf1PVdr2VP3",
251    ///   "contract": {}
252    /// }
253    /// In 0 of [
254    ///   {
255    ///     "account": "2wkBET2rRgE8pahuaczxKbmv7ciehqsne57F9gtzf1PVdr2VP3",
256    ///     "contract": {}
257    ///   }
258    /// ]"#.to_string();
259    /// assert_eq!(expected_verbose, err.display(true));
260    /// ```
261    pub fn display(&self, verbose: bool) -> String { self.display_nested(verbose) }
262
263    /// Gets the underlying error of a [`JsonError::TraceError`]. For any other
264    /// variant, this simply returns the error itself.
265    pub fn get_error(&self) -> &Self { self.get_innermost_error() }
266}
267
268/// Wrapper around a list of bytes to represent data which failed to be
269/// deserialized into schema type.
270#[derive(Debug, Clone)]
271pub struct ToJsonErrorData {
272    pub bytes: Vec<u8>,
273}
274
275impl From<Vec<u8>> for ToJsonErrorData {
276    fn from(bytes: Vec<u8>) -> Self {
277        Self {
278            bytes,
279        }
280    }
281}
282
283impl From<ToJsonErrorData> for Vec<u8> {
284    fn from(value: ToJsonErrorData) -> Self { value.bytes }
285}
286
287impl Display for ToJsonErrorData {
288    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
289        self.bytes.iter().try_for_each(|b| write!(f, "{:02x?}", b))
290    }
291}
292
293/// Represents errors occurring while deserializing to the schema JSON format.
294///
295/// # Examples
296///
297/// ## Simple type from invalid byte sequence
298/// ```
299/// # use serde_json::json;
300/// # use concordium_contracts_common::schema_json::*;
301/// # use concordium_contracts_common::schema::*;
302/// # use concordium_contracts_common::*;
303/// #
304/// let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
305/// let mut cursor = Cursor::new(&account_bytes[..30]); // Malformed account address
306/// let schema = Type::AccountAddress;
307/// let err = schema.to_json(&mut cursor).expect_err("Deserializing should fail");
308///
309/// assert!(matches!(err, ToJsonError::DeserialError {
310///     position: 0,
311///     schema: Type::AccountAddress,
312///     ..
313/// }))
314/// ```
315///
316/// ## Complex type from invalid byte sequence
317/// ```
318/// # use serde_json::json;
319/// # use concordium_contracts_common::schema_json::*;
320/// # use concordium_contracts_common::schema::*;
321/// # use concordium_contracts_common::*;
322/// #
323/// let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
324/// let mut list_bytes = vec![2, 0]; // 2 items in the list
325/// list_bytes.extend_from_slice(&account_bytes); // Correct account address
326/// list_bytes.extend_from_slice(&account_bytes[..30]); // Malformed account address
327///
328/// let mut cursor = Cursor::new(list_bytes);
329/// let schema = Type::List(SizeLength::U8, Box::new(Type::AccountAddress));
330/// let err = schema.to_json(&mut cursor).expect_err("Deserializing should fail");
331///
332/// assert!(matches!(
333///    err,
334///    ToJsonError::TraceError {
335///        position: 0,
336///        schema: Type::List(_, _),
337///        error,
338///    } if matches!(
339///        *error,
340///        ToJsonError::DeserialError {
341///            position: 33,
342///            schema: Type::AccountAddress, ..
343///        }
344///    )
345/// ))
346/// ```
347#[derive(thiserror::Error, Debug, Clone)]
348pub enum ToJsonError {
349    /// JSON formatter failed to represent value.
350    FormatError,
351    /// Failed to deserialize data to type expected from schema.
352    DeserialError {
353        position: u32,
354        schema:   Type,
355        reason:   String,
356        data:     ToJsonErrorData,
357    },
358    /// Trace leading to the original [ToJsonError].
359    TraceError {
360        position: u32,
361        schema:   Type,
362        error:    Box<ToJsonError>,
363    },
364}
365
366impl Display for ToJsonError {
367    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
368        match self {
369            ToJsonError::FormatError => write!(f, "Failed to format as JSON"),
370            ToJsonError::DeserialError {
371                position,
372                schema,
373                reason,
374                data,
375            } => write!(
376                f,
377                "Failed to deserialize {:?} due to: {} - from position {} of bytes {}",
378                schema, reason, position, data
379            ),
380            ToJsonError::TraceError {
381                ..
382            } => write!(f, "{}", self.display(false)),
383        }
384    }
385}
386
387impl TraceError for ToJsonError {
388    fn display_layer(&self, verbose: bool) -> (String, Option<&Self>) {
389        if let ToJsonError::TraceError {
390            error,
391            position,
392            schema,
393        } = self
394        {
395            let message = if verbose {
396                format!("In deserializing position {} into type {:?}", position, schema)
397            } else {
398                format!("{:?}", schema)
399            };
400
401            return (message, Some(error));
402        }
403
404        let message = format!("{}", self);
405        (message, None)
406    }
407
408    fn get_inner_error(&self) -> Option<&Self> {
409        if let ToJsonError::TraceError {
410            error,
411            ..
412        } = self
413        {
414            return Some(error);
415        }
416
417        None
418    }
419}
420
421impl ToJsonError {
422    /// Wraps a [`ToJsonError`] in a [`ToJsonError::TraceError`], providing a
423    /// trace to the origin of the error.
424    fn add_trace(self, position: u32, schema: &Type) -> Self {
425        ToJsonError::TraceError {
426            position,
427            schema: schema.clone(),
428            error: Box::new(self),
429        }
430    }
431
432    /// Returns a formatted error message for variant.
433    /// [`ToJsonError::TraceError`] supports printing a verbose form
434    /// including a more detailed description of the error stack, which is
435    /// returned if `verbose` is set to true.
436    ///
437    /// # Examples
438    ///
439    /// ## Display error from failing to deserialize to list of objects
440    ///
441    /// ```
442    /// # use serde_json::json;
443    /// # use concordium_contracts_common::schema_json::*;
444    /// # use concordium_contracts_common::schema::*;
445    /// # use concordium_contracts_common::*;
446    /// #
447    /// let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
448    /// let contract_bytes = [0u8; 16];
449    /// let mut list_bytes = vec![2, 0];
450    /// list_bytes.extend_from_slice(&account_bytes);
451    /// list_bytes.extend_from_slice(&contract_bytes);
452    /// // r#"<error-message>
453    /// // In deserializing position <cursor-position> into type Struct(...)
454    /// // In deserializing position <cursor-position> into type List(...)"#;
455    /// list_bytes.extend_from_slice(&account_bytes);
456    /// list_bytes.extend_from_slice(&contract_bytes[..10]); // Malformed contract address.
457
458    /// let mut cursor = Cursor::new(list_bytes.clone());
459    /// let schema_object = Type::Struct(Fields::Named(vec![
460    ///     ("a".into(), Type::AccountAddress),
461    ///     ("b".into(), Type::ContractAddress),
462    /// ]));
463    /// let schema = Type::List(SizeLength::U8, Box::new(schema_object));
464    /// let err = schema.to_json(&mut cursor)
465    ///                 .expect_err("Deserializing should fail");
466    ///
467    /// // The error format points to the position in the byte sequence that
468    /// // failed to deserialize:
469    /// err.display(false); // "List(...) -> Struct(...) -> <error-message>");
470    ///
471    /// // Or if verbose, includes a stacktrace-like format, similar to:
472    /// // r#"<error-message>
473    /// // In deserializing position <cursor-position> into type Struct(...)
474    /// // In deserializing position <cursor-position> into type List(...)"#;
475    /// err.display(true);
476    /// ```
477    pub fn display(&self, verbose: bool) -> String { self.display_nested(verbose) }
478
479    /// Gets the underlying error of a [`ToJsonError::TraceError`]. For any
480    /// other variant, this simply returns the error itself.
481    pub fn get_error(&self) -> &Self { self.get_innermost_error() }
482}
483
484/// Error with the sole purpose of adding some context to [`ParseError`].
485#[derive(thiserror::Error, Debug, Clone)]
486#[error("{0}")]
487struct ParseErrorWithReason(String);
488
489// Serializes a value to the provided output buffer
490macro_rules! serial {
491    ($value:ident, $out:ident) => {
492        $value.serial($out).or(Err(JsonError::FailedWriting))
493    };
494}
495
496// Either the given condition holds otherwise the provided error and
497// accompanying message is returned
498macro_rules! ensure {
499    ($cond:expr, $err:expr) => {
500        if !$cond {
501            return Err($err);
502        }
503    };
504}
505
506/// Uses the schema to parse JSON into bytes
507/// It is assumed the array of values for Map and Set are already ordered.
508fn write_bytes_from_json_schema_type<W: Write>(
509    schema: &Type,
510    json: &serde_json::Value,
511    out: &mut W,
512) -> Result<(), JsonError> {
513    use JsonError::*;
514
515    match schema {
516        Type::Unit => Ok(()),
517        Type::Bool => {
518            if let Value::Bool(b) = json {
519                serial!(b, out)
520            } else {
521                Err(WrongJsonType("JSON boolean required".to_string()))
522            }
523        }
524        Type::U8 => {
525            if let Value::Number(n) = json {
526                let n = n.as_u64().ok_or(JsonError::UnsignedIntRequired)?;
527                let n: u8 = n.try_into()?;
528                serial!(n, out)
529            } else {
530                Err(WrongJsonType("JSON number required".to_string()))
531            }
532        }
533        Type::U16 => {
534            if let Value::Number(n) = json {
535                let n = n.as_u64().ok_or(JsonError::UnsignedIntRequired)?;
536                let n: u16 = n.try_into()?;
537                serial!(n, out)
538            } else {
539                Err(WrongJsonType("JSON number required".to_string()))
540            }
541        }
542        Type::U32 => {
543            if let Value::Number(n) = json {
544                let n = n.as_u64().ok_or(JsonError::UnsignedIntRequired)?;
545                let n: u32 = n.try_into()?;
546                serial!(n, out)
547            } else {
548                Err(WrongJsonType("JSON number required".to_string()))
549            }
550        }
551        Type::U64 => {
552            if let Value::Number(n) = json {
553                let n = n.as_u64().ok_or(JsonError::UnsignedIntRequired)?;
554                serial!(n, out)
555            } else {
556                Err(WrongJsonType("JSON number required".to_string()))
557            }
558        }
559        Type::I8 => {
560            if let Value::Number(n) = json {
561                let n = n.as_i64().ok_or(JsonError::SignedIntRequired)?;
562                let n: i8 = n.try_into()?;
563                serial!(n, out)
564            } else {
565                Err(WrongJsonType("JSON number required".to_string()))
566            }
567        }
568        Type::I16 => {
569            if let Value::Number(n) = json {
570                let n = n.as_i64().ok_or(JsonError::SignedIntRequired)?;
571                let n: i16 = n.try_into()?;
572                serial!(n, out)
573            } else {
574                Err(WrongJsonType("JSON number required".to_string()))
575            }
576        }
577        Type::I32 => {
578            if let Value::Number(n) = json {
579                let n = n.as_i64().ok_or(JsonError::SignedIntRequired)?;
580                let n: i32 = n.try_into()?;
581                serial!(n, out)
582            } else {
583                Err(WrongJsonType("JSON number required".to_string()))
584            }
585        }
586        Type::I64 => {
587            if let Value::Number(n) = json {
588                let n = n.as_i64().ok_or(JsonError::SignedIntRequired)?;
589                serial!(n, out)
590            } else {
591                Err(WrongJsonType("JSON number required".to_string()))
592            }
593        }
594        Type::Amount => {
595            if let Value::String(string) = json {
596                let amount: u64 = string.parse()?;
597                serial!(amount, out)
598            } else {
599                Err(WrongJsonType("JSON string required".to_string()))
600            }
601        }
602        Type::AccountAddress => {
603            if let Value::String(string) = json {
604                let account: AccountAddress =
605                    string.parse().or(Err(JsonError::FailedParsingAccountAddress))?;
606                serial!(account, out)
607            } else {
608                Err(WrongJsonType("JSON string required".to_string()))
609            }
610        }
611        Type::ContractAddress => {
612            if let Value::Object(fields) = json {
613                ensure!(
614                    fields.len() <= 2,
615                    FieldError("Only index and optionally subindex are allowed".to_string())
616                );
617
618                let index = fields
619                    .get("index")
620                    .and_then(|v| match v {
621                        Value::Number(n) => n.as_u64(),
622                        _ => None,
623                    })
624                    .ok_or_else(|| {
625                        FieldError("'index' is required in a Contract address".to_string())
626                    })?;
627                let subindex = fields
628                    .get("subindex")
629                    .and_then(|v| match v {
630                        Value::Number(n) => n.as_u64(),
631                        _ => None,
632                    })
633                    .unwrap_or(0);
634                let contract = ContractAddress {
635                    index,
636                    subindex,
637                };
638                serial!(contract, out)
639            } else {
640                Err(WrongJsonType("JSON Object with 'index' field required".to_string()))
641            }
642        }
643        Type::Timestamp => {
644            if let Value::String(string) = json {
645                let timestamp: Timestamp = string.parse()?;
646                serial!(timestamp, out)
647            } else {
648                Err(WrongJsonType("JSON String required for timestamp".to_string()))
649            }
650        }
651        Type::Duration => {
652            if let Value::String(string) = json {
653                let duration: Duration = string.parse()?;
654                serial!(duration, out)
655            } else {
656                Err(WrongJsonType("JSON String required for duration".to_string()))
657            }
658        }
659        Type::Pair(left_type, right_type) => {
660            if let Value::Array(values) = json {
661                ensure!(
662                    values.len() == 2,
663                    PairError("Only pairs of two are supported".to_string())
664                );
665                write_bytes_from_json_schema_type(left_type, &values[0], out)
666                    .map_err(|e| e.add_trace("0".to_string(), json))?;
667                write_bytes_from_json_schema_type(right_type, &values[1], out)
668                    .map_err(|e| e.add_trace("1".to_string(), json))
669            } else {
670                Err(WrongJsonType("JSON Array required for a pair".to_string()))
671            }
672        }
673        Type::List(size_len, ty) => {
674            if let Value::Array(values) = json {
675                let len = values.len();
676                write_bytes_for_length_of_size(len, size_len, out)?;
677
678                for (i, value) in values.iter().enumerate() {
679                    write_bytes_from_json_schema_type(ty, value, out)
680                        .map_err(|e| e.add_trace(format!("{}", i), json))?;
681                }
682                Ok(())
683            } else {
684                Err(WrongJsonType("JSON Array required".to_string()))
685            }
686        }
687        Type::Set(size_len, ty) => {
688            if let Value::Array(values) = json {
689                let len = values.len();
690                write_bytes_for_length_of_size(len, size_len, out)?;
691
692                for (i, value) in values.iter().enumerate() {
693                    write_bytes_from_json_schema_type(ty, value, out)
694                        .map_err(|e| e.add_trace(format!("{}", i), json))?;
695                }
696                Ok(())
697            } else {
698                Err(WrongJsonType("JSON Array required".to_string()))
699            }
700        }
701        Type::Map(size_len, key_ty, val_ty) => {
702            if let Value::Array(entries) = json {
703                let len = entries.len();
704                write_bytes_for_length_of_size(len, size_len, out)?;
705
706                for (i, entry) in entries.iter().enumerate() {
707                    if let Value::Array(pair) = entry {
708                        ensure!(pair.len() == 2, MapError("Expected key-value pair".to_string()));
709                        let result: Result<(), JsonError> = {
710                            write_bytes_from_json_schema_type(key_ty, &pair[0], out)
711                                .map_err(|e| e.add_trace("0".to_string(), entry))?;
712                            write_bytes_from_json_schema_type(val_ty, &pair[1], out)
713                                .map_err(|e| e.add_trace("1".to_string(), entry))?;
714                            Ok(())
715                        };
716                        result.map_err(|e| e.add_trace(format!("{}", i), json))?;
717                    } else {
718                        return Err(WrongJsonType(
719                            "Expected key value pairs as JSON arrays".to_string(),
720                        ));
721                    }
722                }
723                Ok(())
724            } else {
725                Err(WrongJsonType("JSON Array required".to_string()))
726            }
727        }
728        Type::Array(len, ty) => {
729            if let Value::Array(values) = json {
730                ensure!(
731                    (values.len() as u32) == *len,
732                    ArrayError(format!(
733                        "Expected array with {} elements, but it had {} elements",
734                        len,
735                        values.len()
736                    ))
737                );
738
739                for (i, value) in values.iter().enumerate() {
740                    write_bytes_from_json_schema_type(ty, value, out)
741                        .map_err(|e| e.add_trace(format!("{}", i), json))?;
742                }
743                Ok(())
744            } else {
745                Err(WrongJsonType("JSON Array required".to_string()))
746            }
747        }
748        Type::Struct(fields_ty) => write_bytes_from_json_schema_fields(fields_ty, json, out),
749        Type::Enum(variants_ty) => {
750            if let Value::Object(map) = json {
751                ensure!(map.len() == 1, EnumError("Only one variant allowed".to_string()));
752                let (variant_name, fields_value) = map.iter().next().unwrap(); // Safe since we already checked the length
753                let schema_fields_opt = variants_ty
754                    .iter()
755                    .enumerate()
756                    .find(|(_, (variant_name_schema, _))| variant_name_schema == variant_name);
757                if let Some((i, (_, variant_fields))) = schema_fields_opt {
758                    if variants_ty.len() <= 256 {
759                        out.write_u8(i as u8).or(Err(JsonError::FailedWriting))?;
760                    } else if variants_ty.len() <= 256 * 256 {
761                        out.write_u16(i as u16).or(Err(JsonError::FailedWriting))?;
762                    } else {
763                        return Err(EnumError(
764                            "Enums with more than 65536 variants are not supported.".to_string(),
765                        ));
766                    };
767                    write_bytes_from_json_schema_fields(variant_fields, fields_value, out)
768                        .map_err(|e| e.add_trace(format!("\"{}\"", variant_name), json))
769                } else {
770                    // Non-existing variant
771                    Err(EnumError(format!("Unknown variant: {}", variant_name)))
772                }
773            } else {
774                Err(WrongJsonType("JSON Object with one field required for an Enum".to_string()))
775            }
776        }
777        Type::TaggedEnum(variants_ty) => {
778            if let Value::Object(fields) = json {
779                ensure!(fields.len() == 1, EnumError("Only one variant allowed.".to_string()));
780                let (variant_name, fields_value) = fields.iter().next().unwrap(); // Safe since we already checked the length
781                let schema_fields_opt = variants_ty
782                    .iter()
783                    .find(|(_, (variant_name_schema, _))| variant_name_schema == variant_name);
784                if let Some((&i, (_, variant_fields))) = schema_fields_opt {
785                    out.write_u8(i).or(Err(JsonError::FailedWriting))?;
786                    write_bytes_from_json_schema_fields(variant_fields, fields_value, out)
787                        .map_err(|e| e.add_trace(format!("'{}'", variant_name), json))
788                } else {
789                    // Non-existing variant
790                    Err(EnumError(format!("Unknown variant: {}", variant_name)))
791                }
792            } else {
793                Err(WrongJsonType("JSON Object required for an EnumTag".to_string()))
794            }
795        }
796        Type::String(size_len) => {
797            if let Value::String(string) = json {
798                let len = string.len();
799                write_bytes_for_length_of_size(len, size_len, out)?;
800                serial_vector_no_length(string.as_bytes(), out).or(Err(JsonError::FailedWriting))
801            } else {
802                Err(WrongJsonType("JSON String required".to_string()))
803            }
804        }
805        Type::ContractName(size_len) => {
806            if let Value::Object(fields) = json {
807                let contract = fields.get("contract").ok_or_else(|| {
808                    FieldError("Missing field \"contract\" of type JSON String.".to_string())
809                })?;
810                ensure!(
811                    fields.len() == 1,
812                    FieldError(format!(
813                        "Expected only one field but {} were provided.",
814                        fields.len()
815                    ))
816                );
817                if let Value::String(name) = contract {
818                    let contract_name = format!("init_{}", name);
819                    let len = contract_name.len();
820                    write_bytes_for_length_of_size(len, size_len, out)?;
821                    serial_vector_no_length(contract_name.as_bytes(), out)
822                        .or(Err(JsonError::FailedWriting))
823                } else {
824                    Err(WrongJsonType("JSON String required for field \"contract\".".to_string()))
825                }
826            } else {
827                Err(WrongJsonType("JSON Object required for contract name.".to_string()))
828            }
829        }
830        Type::ReceiveName(size_len) => {
831            if let Value::Object(fields) = json {
832                let contract = fields.get("contract").ok_or_else(|| {
833                    FieldError("Missing field \"contract\" of type JSON String.".to_string())
834                })?;
835                let func = fields.get("func").ok_or_else(|| {
836                    WrongJsonType("Missing field \"func\" of type JSON String.".to_string())
837                })?;
838                ensure!(
839                    fields.len() == 2,
840                    FieldError(format!(
841                        "Expected exactly two fields but {} were provided.",
842                        fields.len()
843                    ))
844                );
845                if let Value::String(contract) = contract {
846                    if let Value::String(func) = func {
847                        let receive_name = format!("{}.{}", contract, func);
848                        let len = receive_name.len();
849                        write_bytes_for_length_of_size(len, size_len, out)?;
850                        serial_vector_no_length(receive_name.as_bytes(), out)
851                            .or(Err(JsonError::FailedWriting))
852                    } else {
853                        Err(WrongJsonType("JSON String required for field \"func\".".to_string()))
854                    }
855                } else {
856                    Err(WrongJsonType("JSON String required for field \"contract\".".to_string()))
857                }
858            } else {
859                Err(WrongJsonType("JSON Object required for contract name.".to_string()))
860            }
861        }
862        Type::U128 => {
863            if let Value::String(string) = json {
864                let n: u128 = string
865                    .parse()
866                    .map_err(|_| ParseError("Could not parse as u128.".to_string()))?;
867                serial!(n, out)
868            } else {
869                Err(WrongJsonType("JSON String required".to_string()))
870            }
871        }
872        Type::I128 => {
873            if let Value::String(string) = json {
874                let n: i128 = string
875                    .parse()
876                    .map_err(|_| ParseError("Could not parse as i128.".to_string()))?;
877                serial!(n, out)
878            } else {
879                Err(WrongJsonType("JSON String required".to_string()))
880            }
881        }
882        Type::ULeb128(constraint) => {
883            if let Value::String(string) = json {
884                let biguint = string
885                    .parse()
886                    .map_err(|_| ParseError("Could not parse integer.".to_string()))?;
887                serial_biguint(biguint, *constraint, out).or(Err(JsonError::FailedWriting))
888            } else {
889                Err(WrongJsonType("JSON String required".to_string()))
890            }
891        }
892        Type::ILeb128(constraint) => {
893            if let Value::String(string) = json {
894                let bigint = string
895                    .parse()
896                    .map_err(|_| ParseError("Could not parse integer.".to_string()))?;
897                serial_bigint(bigint, *constraint, out).or(Err(JsonError::FailedWriting))
898            } else {
899                Err(WrongJsonType("JSON String required".to_string()))
900            }
901        }
902        Type::ByteList(size_len) => {
903            if let Value::String(string) = json {
904                let bytes = hex::decode(string)?;
905                let len = bytes.len();
906                write_bytes_for_length_of_size(len, size_len, out)?;
907                for value in bytes {
908                    serial!(value, out)?
909                }
910                Ok(())
911            } else {
912                Err(WrongJsonType("JSON String required".to_string()))
913            }
914        }
915        Type::ByteArray(len) => {
916            if let Value::String(string) = json {
917                let bytes = hex::decode(string)?;
918                ensure!(
919                    *len == bytes.len() as u32,
920                    ByteArrayError("Mismatching number of bytes".to_string())
921                );
922                for value in bytes {
923                    serial!(value, out)?;
924                }
925                Ok(())
926            } else {
927                Err(WrongJsonType("JSON String required".to_string()))
928            }
929        }
930    }
931}
932
933impl Fields {
934    /// Displays a template of the JSON to be used for the [`Fields`].
935    pub fn to_json_template(&self) -> serde_json::Value {
936        match self {
937            Fields::Named(vec) => {
938                let mut map = Map::new();
939
940                for (name, field) in vec.iter() {
941                    map.insert(name.to_string(), field.to_json_template());
942                }
943
944                map.into()
945            }
946            Fields::Unnamed(vec) => {
947                let mut new_vector = Vec::new();
948                for element in vec.iter() {
949                    new_vector.push(element.to_json_template())
950                }
951
952                new_vector.into()
953            }
954            Fields::None => serde_json::Value::Array(Vec::new()),
955        }
956    }
957}
958
959/// Displays a pretty-printed JSON-template of the [`Type`].
960impl Display for Type {
961    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
962        write!(f, "{}", serde_json::to_string_pretty(&self.to_json_template()).unwrap())
963    }
964}
965
966/// Displays the json template of the type indented.
967/// The `type_schema_name` is indented by `indent` and the associated
968/// `type_schema` is indented by `indent + 2` because the `type_schema` is
969/// one level deeper than the `type_schema_name` and therefore indented by `+
970/// 2`. '\n' is replaced by `replace_new_line` (e.g. "\n        ") because the
971/// `VersionedModuleSchema` template has several higher level outputs (e.g.
972/// `contractNames`, `functionNames`, ...).
973fn display_json_template_indented(
974    mut out: String,
975    type_schema: &Type,
976    type_schema_name: &str,
977    indent: usize,
978    replace_new_line: &str,
979) -> String {
980    // `{:>3$}` right-alignes the "" value in the column. The column width is
981    // defined by the last argument (`3$` == `indent`). This creates the
982    // correct tabs/whitespace. https://doc.rust-lang.org/std/fmt/#fillalignment
983    out = format!("{}{:>3$}{}:\n", out, "", type_schema_name, indent);
984    out = format!(
985        "{}{:>3$}{}\n",
986        out,
987        "",
988        type_schema.to_string().replace('\n', replace_new_line),
989        indent + 2
990    );
991    out
992}
993
994/// Displays a pretty-printed template of the [`VersionedModuleSchema`].
995///
996/// # Examples
997///
998/// ## Display a template of the `VersionedModuleSchema`
999///
1000/// ```
1001/// # use serde_json::json;
1002/// # use concordium_contracts_common::schema_json::*;
1003/// # use concordium_contracts_common::schema::*;
1004/// # use concordium_contracts_common::*;
1005/// # use std::collections::BTreeMap;
1006/// #
1007/// let mut receive_function_map = BTreeMap::new();
1008/// receive_function_map.insert(String::from("MyFunction"), FunctionV2 {
1009///     parameter:    Some(Type::AccountAddress),
1010///     error:        Some(Type::AccountAddress),
1011///     return_value: Some(Type::AccountAddress),
1012/// });
1013///
1014/// let mut map = BTreeMap::new();
1015///
1016/// map.insert(String::from("MyContract"), ContractV3 {
1017///     init:    Some(FunctionV2 {
1018///         parameter:    Some(Type::AccountAddress),
1019///         error:        Some(Type::AccountAddress),
1020///         return_value: Some(Type::AccountAddress),
1021///     }),
1022///     receive: receive_function_map,
1023///     event:   Some(Type::AccountAddress),
1024/// });
1025///
1026/// let schema = VersionedModuleSchema::V3(ModuleV3 {
1027///     contracts: map,
1028/// });
1029///
1030/// let display = "Contract:  MyContract
1031///   Init:
1032///     Parameter:
1033///       \"<AccountAddress>\"
1034///     Error:
1035///       \"<AccountAddress>\"
1036///     Return value:
1037///       \"<AccountAddress>\"
1038///   Methods:
1039///     - \"MyFunction\"
1040///       Parameter:
1041///         \"<AccountAddress>\"
1042///       Error:
1043///         \"<AccountAddress>\"
1044///       Return value:
1045///         \"<AccountAddress>\"
1046///   Event:
1047///     \"<AccountAddress>\"\n";
1048///
1049/// assert_eq!(display, format!("{}", schema));
1050/// ```
1051impl Display for VersionedModuleSchema {
1052    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1053        let mut out = String::new();
1054        match self {
1055            VersionedModuleSchema::V0(module_v0) => {
1056                for (contract_name, contract_schema) in module_v0.contracts.iter() {
1057                    out = format!("{}Contract: {:>11}\n", out, contract_name);
1058                    // State
1059                    if let Some(type_schema) = &contract_schema.state {
1060                        out = format!("{}{:>2}State:\n", out, "");
1061                        out = format!(
1062                            "{}{:>4}{}\n",
1063                            out,
1064                            "",
1065                            type_schema.to_string().replace('\n', "\n    ")
1066                        );
1067                    }
1068                    // Init Function
1069                    if let Some(type_schema) = &contract_schema.init {
1070                        out = format!("{}{:>2}Init:\n", out, "");
1071                        out = format!(
1072                            "{}{:>4}{}\n",
1073                            out,
1074                            "",
1075                            type_schema.to_string().replace('\n', "\n      ")
1076                        );
1077                    }
1078                    // Receive Functions
1079                    let receive_functions_map = &contract_schema.receive;
1080                    if !receive_functions_map.is_empty() {
1081                        out = format!("{}{:>2}Methods:\n", out, "");
1082                    }
1083
1084                    for (function_name, type_schema) in receive_functions_map.iter() {
1085                        out = format!("{}{:>4}- {:?}\n", out, "", function_name);
1086                        out = format!(
1087                            "{}{:>6}{}\n",
1088                            out,
1089                            "",
1090                            type_schema.to_string().replace('\n', "\n      ")
1091                        );
1092                    }
1093                }
1094            }
1095            VersionedModuleSchema::V1(module_v1) => {
1096                for (contract_name, contract_schema) in module_v1.contracts.iter() {
1097                    out = format!("{}Contract: {:>11}\n", out, contract_name);
1098                    // Init Function
1099                    if let Some(schema) = &contract_schema.init {
1100                        out = format!("{}{:>2}Init:\n", out, "");
1101
1102                        if let Some(type_schema) = schema.parameter() {
1103                            out = display_json_template_indented(
1104                                out,
1105                                type_schema,
1106                                "Parameter",
1107                                4,
1108                                "\n      ",
1109                            )
1110                        }
1111                        if let Some(type_schema) = schema.return_value() {
1112                            out = display_json_template_indented(
1113                                out,
1114                                type_schema,
1115                                "Return value",
1116                                4,
1117                                "\n      ",
1118                            )
1119                        }
1120                    }
1121
1122                    // Receive Functions
1123                    let receive_functions_map = &contract_schema.receive;
1124                    if !receive_functions_map.is_empty() {
1125                        out = format!("{}{:>2}Methods:\n", out, "");
1126                    }
1127
1128                    for (function_name, schema) in receive_functions_map.iter() {
1129                        out = format!("{}{:>4}- {:?}\n", out, "", function_name);
1130
1131                        if let Some(type_schema) = schema.parameter() {
1132                            out = display_json_template_indented(
1133                                out,
1134                                type_schema,
1135                                "Parameter",
1136                                6,
1137                                "\n        ",
1138                            )
1139                        }
1140                        if let Some(type_schema) = schema.return_value() {
1141                            out = display_json_template_indented(
1142                                out,
1143                                type_schema,
1144                                "Return value",
1145                                6,
1146                                "\n        ",
1147                            )
1148                        }
1149                    }
1150                }
1151            }
1152            VersionedModuleSchema::V2(module_v2) => {
1153                for (contract_name, contract_schema) in module_v2.contracts.iter() {
1154                    out = format!("{}Contract: {:>11}\n", out, contract_name);
1155                    // Init Function
1156                    if let Some(FunctionV2 {
1157                        parameter,
1158                        return_value,
1159                        error,
1160                    }) = &contract_schema.init
1161                    {
1162                        out = format!("{}{:>2}Init:\n", out, "");
1163
1164                        if let Some(type_schema) = parameter {
1165                            out = display_json_template_indented(
1166                                out,
1167                                type_schema,
1168                                "Parameter",
1169                                4,
1170                                "\n      ",
1171                            )
1172                        }
1173
1174                        if let Some(type_schema) = error {
1175                            out = display_json_template_indented(
1176                                out,
1177                                type_schema,
1178                                "Error",
1179                                4,
1180                                "\n      ",
1181                            )
1182                        }
1183
1184                        if let Some(type_schema) = return_value {
1185                            out = display_json_template_indented(
1186                                out,
1187                                type_schema,
1188                                "Return value",
1189                                4,
1190                                "\n      ",
1191                            )
1192                        }
1193                    }
1194                    // Receive Functions
1195                    let receive_functions_map = &contract_schema.receive;
1196                    if !receive_functions_map.is_empty() {
1197                        out = format!("{}{:>2}Methods:\n", out, "");
1198                    }
1199
1200                    for (function_name, schema) in receive_functions_map.iter() {
1201                        out = format!("{}{:>4}- {:?}\n", out, "", function_name);
1202
1203                        let FunctionV2 {
1204                            parameter,
1205                            return_value,
1206                            error,
1207                        } = schema;
1208
1209                        if let Some(type_schema) = parameter {
1210                            out = display_json_template_indented(
1211                                out,
1212                                type_schema,
1213                                "Parameter",
1214                                6,
1215                                "\n        ",
1216                            )
1217                        }
1218
1219                        if let Some(type_schema) = error {
1220                            out = display_json_template_indented(
1221                                out,
1222                                type_schema,
1223                                "Error",
1224                                6,
1225                                "\n        ",
1226                            )
1227                        }
1228
1229                        if let Some(type_schema) = return_value {
1230                            out = display_json_template_indented(
1231                                out,
1232                                type_schema,
1233                                "Return value",
1234                                6,
1235                                "\n        ",
1236                            )
1237                        }
1238                    }
1239                }
1240            }
1241            VersionedModuleSchema::V3(module_v3) => {
1242                for (contract_name, contract_schema) in module_v3.contracts.iter() {
1243                    out = format!("{}Contract: {:>11}\n", out, contract_name);
1244
1245                    // Init Function
1246                    if let Some(FunctionV2 {
1247                        parameter,
1248                        return_value,
1249                        error,
1250                    }) = &contract_schema.init
1251                    {
1252                        out = format!("{}{:>2}Init:\n", out, "");
1253
1254                        if let Some(type_schema) = parameter {
1255                            out = display_json_template_indented(
1256                                out,
1257                                type_schema,
1258                                "Parameter",
1259                                4,
1260                                "\n      ",
1261                            )
1262                        }
1263
1264                        if let Some(type_schema) = error {
1265                            out = display_json_template_indented(
1266                                out,
1267                                type_schema,
1268                                "Error",
1269                                4,
1270                                "\n      ",
1271                            )
1272                        }
1273
1274                        if let Some(type_schema) = return_value {
1275                            out = display_json_template_indented(
1276                                out,
1277                                type_schema,
1278                                "Return value",
1279                                4,
1280                                "\n      ",
1281                            )
1282                        }
1283                    }
1284
1285                    // Receive Functions
1286                    let receive_functions_map = &contract_schema.receive;
1287
1288                    if !receive_functions_map.is_empty() {
1289                        out = format!("{}{:>2}Methods:\n", out, "");
1290                    }
1291
1292                    for (function_name, schema) in receive_functions_map.iter() {
1293                        out = format!("{}{:>4}- {:?}\n", out, "", function_name);
1294
1295                        let FunctionV2 {
1296                            parameter,
1297                            return_value,
1298                            error,
1299                        } = schema;
1300
1301                        if let Some(type_schema) = parameter {
1302                            out = display_json_template_indented(
1303                                out,
1304                                type_schema,
1305                                "Parameter",
1306                                6,
1307                                "\n        ",
1308                            )
1309                        }
1310
1311                        if let Some(type_schema) = error {
1312                            out = display_json_template_indented(
1313                                out,
1314                                type_schema,
1315                                "Error",
1316                                6,
1317                                "\n        ",
1318                            )
1319                        }
1320
1321                        if let Some(type_schema) = return_value {
1322                            out = display_json_template_indented(
1323                                out,
1324                                type_schema,
1325                                "Return value",
1326                                6,
1327                                "\n        ",
1328                            )
1329                        }
1330                    }
1331
1332                    // Event
1333                    if let Some(type_schema) = &contract_schema.event {
1334                        out = format!("{}{:>2}Event:\n", out, "");
1335                        out = format!(
1336                            "{}{:>4}{}\n",
1337                            out,
1338                            "",
1339                            type_schema.to_string().replace('\n', "\n    ")
1340                        );
1341                    }
1342                }
1343            }
1344        }
1345        write!(f, "{}", out)
1346    }
1347}
1348
1349impl Type {
1350    /// Serialize the given JSON value into the binary format represented by the
1351    /// schema. If the JSON value does not match the schema an error will be
1352    /// returned.
1353    pub fn serial_value(&self, json: &serde_json::Value) -> Result<Vec<u8>, JsonError> {
1354        let mut out = Vec::new();
1355        self.serial_value_into(json, &mut out)?;
1356        Ok(out)
1357    }
1358
1359    /// Serialize the given JSON value into the binary format represented by the
1360    /// schema. The resulting byte array is written into the provided sink.
1361    /// If the JSON value does not match the schema an error will be returned.
1362    pub fn serial_value_into(
1363        &self,
1364        json: &serde_json::Value,
1365        out: &mut impl Write,
1366    ) -> Result<(), JsonError> {
1367        write_bytes_from_json_schema_type(self, json, out)
1368    }
1369
1370    /// Uses the schema to parse JSON into bytes
1371    /// It is assumed the array of values for Map and Set are already ordered.
1372    #[deprecated(
1373        since = "5.2.0",
1374        note = "Use the more ergonomic [`serial_value_into`](Self::serial_value_into) instead."
1375    )]
1376    pub fn write_bytes_from_json_schema_type<W: Write>(
1377        schema: &Type,
1378        json: &serde_json::Value,
1379        out: &mut W,
1380    ) -> Result<(), JsonError> {
1381        write_bytes_from_json_schema_type(schema, json, out)
1382    }
1383
1384    /// Displays a template of the JSON to be used for the [`SchemaType`].
1385    pub fn to_json_template(&self) -> serde_json::Value {
1386        match self {
1387            Self::Enum(enum_type) => {
1388                let mut outer_map = Map::new();
1389
1390                let mut vector = Vec::new();
1391
1392                for (name, field) in enum_type.iter() {
1393                    let mut inner_map = Map::new();
1394                    inner_map.insert(name.to_string(), field.to_json_template());
1395                    vector.push(json!(inner_map))
1396                }
1397                outer_map.insert("Enum".to_string(), json!(vector));
1398
1399                outer_map.into()
1400            }
1401            Self::TaggedEnum(tagged_enum) => {
1402                let mut outer_map = Map::new();
1403
1404                let mut vector = Vec::new();
1405
1406                for (_tag, (name, field)) in tagged_enum.iter() {
1407                    let mut inner_map = Map::new();
1408                    inner_map.insert(name.to_string(), field.to_json_template());
1409                    vector.push(json!(inner_map))
1410                }
1411                outer_map.insert("Enum".to_string(), json!(vector));
1412
1413                outer_map.into()
1414            }
1415            Self::Struct(field) => field.to_json_template(),
1416            Self::ByteList(_) => "<String with lowercase hex>".into(),
1417            Self::ByteArray(size) => {
1418                let string_size = 2 * size;
1419                format!("<String of size {string_size} containing lowercase hex characters.>")
1420                    .into()
1421            }
1422            Self::String(_) => "<String>".into(),
1423            Self::Unit => serde_json::Value::Array(Vec::new()),
1424            Self::Bool => "<Bool>".into(),
1425            Self::U8 => "<UInt8>".into(),
1426            Self::U16 => "<UInt16>".into(),
1427            Self::U32 => "<UInt32>".into(),
1428            Self::U64 => "<UInt64>".into(),
1429            Self::U128 => "<UInt128>".into(),
1430            Self::I8 => "<Int8>".into(),
1431            Self::I16 => "<Int16>".into(),
1432            Self::I32 => "<Int32>".into(),
1433            Self::I64 => "<Int64>".into(),
1434            Self::I128 => "<Int128>".into(),
1435            Self::ILeb128(size) => {
1436                let string_size = 2 * size;
1437                format!("<String of size at most {string_size} containing a signed integer.>")
1438                    .into()
1439            }
1440            Self::ULeb128(size) => {
1441                let string_size = 2 * size;
1442                format!("<String of size at most {string_size} containing an unsigned integer.>")
1443                    .into()
1444            }
1445            Self::Amount => "<Amount in microCCD>".into(),
1446            Self::AccountAddress => "<AccountAddress>".into(),
1447            Self::ContractAddress => {
1448                let mut contract_address = Map::new();
1449                contract_address.insert("index".to_string(), Type::U64.to_json_template());
1450                contract_address.insert("subindex".to_string(), Type::U64.to_json_template());
1451                contract_address.into()
1452            }
1453            Self::Timestamp => "<Timestamp (e.g. `2000-01-01T12:00:00Z`)>".into(),
1454            Self::Duration => "<Duration (e.g. `10d 1h 42s`)>".into(),
1455            Self::Pair(a, b) => vec![a.to_json_template(), b.to_json_template()].into(),
1456            Self::List(_, element) => vec![element.to_json_template()].into(),
1457            Self::Array(size, element) => {
1458                let mut vec = Vec::new();
1459                for _i in 0..*size {
1460                    vec.push(element.to_json_template())
1461                }
1462                vec.into()
1463            }
1464            Self::Set(_, element) => vec![element.to_json_template()].into(),
1465            Self::Map(_, key, value) => {
1466                vec![json!(vec![key.to_json_template(), value.to_json_template(),])].into()
1467            }
1468            Self::ContractName(_) => {
1469                let mut contract_name = Map::new();
1470                contract_name.insert("contract".to_string(), "<String>".into());
1471                contract_name.into()
1472            }
1473            Self::ReceiveName(_) => {
1474                let mut receive_name = Map::new();
1475                receive_name.insert("contract".to_string(), "<String>".into());
1476                receive_name.insert("func".to_string(), "<String>".into());
1477                receive_name.into()
1478            }
1479        }
1480    }
1481}
1482
1483fn serial_biguint<W: Write>(bigint: BigUint, constraint: u32, out: &mut W) -> Result<(), W::Err> {
1484    let mut value = bigint;
1485    for _ in 0..constraint {
1486        // Read the first byte of the value
1487        let mut byte = value.iter_u32_digits().next().unwrap_or(0) as u8;
1488        byte &= 0b0111_1111;
1489        value >>= 7;
1490        if !value.is_zero() {
1491            byte |= 0b1000_0000;
1492        }
1493        out.write_u8(byte)?;
1494
1495        if value.is_zero() {
1496            return Ok(());
1497        }
1498    }
1499    Err(W::Err::default())
1500}
1501
1502fn serial_bigint<W: Write>(bigint: BigInt, constraint: u32, out: &mut W) -> Result<(), W::Err> {
1503    let mut value = bigint;
1504    for _ in 0..constraint {
1505        // Read the first byte of the value
1506        // FIXME: This will allocate a vector where we only need the first byte and can
1507        // hopefully be improved.
1508        let mut byte = value.to_signed_bytes_le()[0] & 0b0111_1111;
1509        value >>= 7;
1510
1511        if (value.is_zero() && (byte & 0b0100_0000) == 0)
1512            || (value == BigInt::from(-1) && (byte & 0b0100_0000) != 0)
1513        {
1514            out.write_u8(byte)?;
1515            return Ok(());
1516        }
1517
1518        byte |= 0b1000_0000;
1519        out.write_u8(byte)?;
1520    }
1521    Err(W::Err::default())
1522}
1523
1524fn write_bytes_from_json_schema_fields<W: Write>(
1525    fields: &Fields,
1526    json: &serde_json::Value,
1527    out: &mut W,
1528) -> Result<(), JsonError> {
1529    use JsonError::*;
1530
1531    match fields {
1532        Fields::Named(fields) => {
1533            if let Value::Object(map) = json {
1534                ensure!(
1535                    fields.len() >= map.len(),
1536                    FieldError("Too many fields provided".to_string())
1537                );
1538                for (field_name, field_ty) in fields {
1539                    let field_value_opt = map.get(field_name);
1540                    if let Some(field_value) = field_value_opt {
1541                        write_bytes_from_json_schema_type(field_ty, field_value, out)
1542                            .map_err(|e| e.add_trace(format!("\"{}\"", field_name), json))?;
1543                    } else {
1544                        return Err(FieldError(format!("Missing field: {}", field_name)));
1545                    }
1546                }
1547                Ok(())
1548            } else {
1549                Err(WrongJsonType("JSON Object required for named fields".to_string()))
1550            }
1551        }
1552        Fields::Unnamed(fields) => {
1553            if let Value::Array(values) = json {
1554                ensure!(
1555                    fields.len() == values.len(),
1556                    FieldError(format!("Expected {} unnamed fields", fields.len()))
1557                );
1558                for (i, (field_ty, value)) in fields.iter().zip(values.iter()).enumerate() {
1559                    write_bytes_from_json_schema_type(field_ty, value, out)
1560                        .map_err(|e| e.add_trace(format!("{}", i), json))?;
1561                }
1562                Ok(())
1563            } else {
1564                Err(WrongJsonType("JSON Array required for unnamed fields".to_string()))
1565            }
1566        }
1567        Fields::None => Ok(()),
1568    }
1569}
1570
1571/// Serializes the length using the number of bytes specified by the size_len.
1572/// Returns an error if the length cannot be represented by the number of bytes.
1573fn write_bytes_for_length_of_size<W: Write>(
1574    len: usize,
1575    size_len: &SizeLength,
1576    out: &mut W,
1577) -> Result<(), JsonError> {
1578    match size_len {
1579        SizeLength::U8 => {
1580            let len: u8 = len.try_into()?;
1581            serial!(len, out)
1582        }
1583        SizeLength::U16 => {
1584            let len: u16 = len.try_into()?;
1585            serial!(len, out)
1586        }
1587        SizeLength::U32 => {
1588            let len: u32 = len.try_into()?;
1589            serial!(len, out)
1590        }
1591        SizeLength::U64 => {
1592            let len: u64 = len.try_into()?;
1593            serial!(len, out)
1594        }
1595    }
1596}
1597
1598#[cfg(test)]
1599mod tests {
1600    use serde_json::json;
1601
1602    use super::*;
1603    use std::collections::BTreeMap;
1604
1605    #[test]
1606    fn test_schema_template_display_module_version_v3_multiple_contracts() {
1607        let mut receive_function_map = BTreeMap::new();
1608        receive_function_map.insert(String::from("MyFunction"), FunctionV2 {
1609            parameter:    Some(Type::AccountAddress),
1610            error:        Some(Type::AccountAddress),
1611            return_value: Some(Type::AccountAddress),
1612        });
1613
1614        let mut map = BTreeMap::new();
1615
1616        map.insert(String::from("MyContract"), ContractV3 {
1617            init:    Some(FunctionV2 {
1618                parameter:    Some(Type::AccountAddress),
1619                error:        Some(Type::AccountAddress),
1620                return_value: Some(Type::AccountAddress),
1621            }),
1622            receive: receive_function_map.clone(),
1623            event:   Some(Type::AccountAddress),
1624        });
1625        map.insert(String::from("MySecondContract"), ContractV3 {
1626            init:    Some(FunctionV2 {
1627                parameter:    Some(Type::AccountAddress),
1628                error:        Some(Type::AccountAddress),
1629                return_value: Some(Type::AccountAddress),
1630            }),
1631            receive: receive_function_map,
1632            event:   Some(Type::AccountAddress),
1633        });
1634
1635        let schema = VersionedModuleSchema::V3(ModuleV3 {
1636            contracts: map,
1637        });
1638
1639        let display = "Contract:  MyContract
1640  Init:
1641    Parameter:
1642      \"<AccountAddress>\"
1643    Error:
1644      \"<AccountAddress>\"
1645    Return value:
1646      \"<AccountAddress>\"
1647  Methods:
1648    - \"MyFunction\"
1649      Parameter:
1650        \"<AccountAddress>\"
1651      Error:
1652        \"<AccountAddress>\"
1653      Return value:
1654        \"<AccountAddress>\"
1655  Event:
1656    \"<AccountAddress>\"
1657Contract: MySecondContract
1658  Init:
1659    Parameter:
1660      \"<AccountAddress>\"
1661    Error:
1662      \"<AccountAddress>\"
1663    Return value:
1664      \"<AccountAddress>\"
1665  Methods:
1666    - \"MyFunction\"
1667      Parameter:
1668        \"<AccountAddress>\"
1669      Error:
1670        \"<AccountAddress>\"
1671      Return value:
1672        \"<AccountAddress>\"
1673  Event:
1674    \"<AccountAddress>\"\n";
1675        assert_eq!(display, format!("{}", schema));
1676    }
1677
1678    /// Tests schema template display of `VersionedModuleSchema::V3`
1679    #[test]
1680    fn test_schema_template_display_module_version_v3() {
1681        let mut receive_function_map = BTreeMap::new();
1682        receive_function_map.insert(String::from("MyFunction"), FunctionV2 {
1683            parameter:    Some(Type::AccountAddress),
1684            error:        Some(Type::AccountAddress),
1685            return_value: Some(Type::AccountAddress),
1686        });
1687
1688        let mut map = BTreeMap::new();
1689
1690        map.insert(String::from("MyContract"), ContractV3 {
1691            init:    Some(FunctionV2 {
1692                parameter:    Some(Type::AccountAddress),
1693                error:        Some(Type::AccountAddress),
1694                return_value: Some(Type::AccountAddress),
1695            }),
1696            receive: receive_function_map,
1697            event:   Some(Type::AccountAddress),
1698        });
1699
1700        let schema = VersionedModuleSchema::V3(ModuleV3 {
1701            contracts: map,
1702        });
1703
1704        let display = "Contract:  MyContract
1705  Init:
1706    Parameter:
1707      \"<AccountAddress>\"
1708    Error:
1709      \"<AccountAddress>\"
1710    Return value:
1711      \"<AccountAddress>\"
1712  Methods:
1713    - \"MyFunction\"
1714      Parameter:
1715        \"<AccountAddress>\"
1716      Error:
1717        \"<AccountAddress>\"
1718      Return value:
1719        \"<AccountAddress>\"
1720  Event:
1721    \"<AccountAddress>\"\n";
1722
1723        assert_eq!(display, format!("{}", schema));
1724    }
1725
1726    /// Tests schema template display of `VersionedModuleSchema::V2`
1727    #[test]
1728    fn test_schema_template_display_module_version_v2() {
1729        let mut receive_function_map = BTreeMap::new();
1730        receive_function_map.insert(String::from("MyFunction"), FunctionV2 {
1731            parameter:    Some(Type::AccountAddress),
1732            error:        Some(Type::AccountAddress),
1733            return_value: Some(Type::AccountAddress),
1734        });
1735
1736        let mut map = BTreeMap::new();
1737
1738        map.insert(String::from("MyContract"), ContractV2 {
1739            init:    Some(FunctionV2 {
1740                parameter:    Some(Type::AccountAddress),
1741                error:        Some(Type::AccountAddress),
1742                return_value: Some(Type::AccountAddress),
1743            }),
1744            receive: receive_function_map,
1745        });
1746
1747        let schema = VersionedModuleSchema::V2(ModuleV2 {
1748            contracts: map,
1749        });
1750
1751        let display = "Contract:  MyContract
1752  Init:
1753    Parameter:
1754      \"<AccountAddress>\"
1755    Error:
1756      \"<AccountAddress>\"
1757    Return value:
1758      \"<AccountAddress>\"
1759  Methods:
1760    - \"MyFunction\"
1761      Parameter:
1762        \"<AccountAddress>\"
1763      Error:
1764        \"<AccountAddress>\"
1765      Return value:
1766        \"<AccountAddress>\"\n";
1767
1768        assert_eq!(display, format!("{}", schema));
1769    }
1770
1771    /// Tests schema template display of `VersionedModuleSchema::V1`
1772    #[test]
1773    fn test_schema_template_display_module_version_v1() {
1774        let mut receive_function_map = BTreeMap::new();
1775        receive_function_map.insert(String::from("MyFunction"), FunctionV1::Both {
1776            parameter:    Type::AccountAddress,
1777            return_value: Type::AccountAddress,
1778        });
1779
1780        let mut map = BTreeMap::new();
1781
1782        map.insert(String::from("MyContract"), ContractV1 {
1783            init:    Some(FunctionV1::Both {
1784                parameter:    Type::AccountAddress,
1785                return_value: Type::AccountAddress,
1786            }),
1787            receive: receive_function_map,
1788        });
1789
1790        let schema = VersionedModuleSchema::V1(ModuleV1 {
1791            contracts: map,
1792        });
1793
1794        let display = "Contract:  MyContract
1795  Init:
1796    Parameter:
1797      \"<AccountAddress>\"
1798    Return value:
1799      \"<AccountAddress>\"
1800  Methods:
1801    - \"MyFunction\"
1802      Parameter:
1803        \"<AccountAddress>\"
1804      Return value:
1805        \"<AccountAddress>\"\n";
1806
1807        assert_eq!(display, format!("{}", schema));
1808    }
1809
1810    /// Tests schema template display of `VersionedModuleSchema::V0`
1811    #[test]
1812    fn test_schema_template_display_module_version_v0() {
1813        let mut receive_function_map = BTreeMap::new();
1814        receive_function_map.insert(String::from("MyFunction"), Type::AccountAddress);
1815
1816        let mut map = BTreeMap::new();
1817
1818        map.insert(String::from("MyContract"), ContractV0 {
1819            state:   Some(Type::AccountAddress),
1820            init:    Some(Type::AccountAddress),
1821            receive: receive_function_map,
1822        });
1823
1824        let schema = VersionedModuleSchema::V0(ModuleV0 {
1825            contracts: map,
1826        });
1827
1828        let display = "Contract:  MyContract
1829  State:
1830    \"<AccountAddress>\"
1831  Init:
1832    \"<AccountAddress>\"
1833  Methods:
1834    - \"MyFunction\"
1835      \"<AccountAddress>\"\n";
1836
1837        assert_eq!(display, format!("{}", schema));
1838    }
1839
1840    /// Tests schema template display in JSON of an Enum
1841    #[test]
1842    fn test_schema_template_display_enum() {
1843        let schema = Type::Enum(Vec::from([(
1844            String::from("Accounts"),
1845            Fields::Unnamed(Vec::from([Type::AccountAddress])),
1846        )]));
1847        assert_eq!(
1848            json!({"Enum": [{"Accounts": ["<AccountAddress>"]}]}),
1849            schema.to_json_template()
1850        );
1851    }
1852
1853    /// Tests schema template display in JSON of an TaggedEnum
1854    #[test]
1855    fn test_schema_template_display_tagged_enum() {
1856        let mut map = BTreeMap::new();
1857        map.insert(
1858            8,
1859            (
1860                String::from("Accounts"),
1861                Fields::Named(Vec::from([(String::from("Account"), Type::AccountAddress)])),
1862            ),
1863        );
1864
1865        let schema = Type::TaggedEnum(map);
1866        assert_eq!(
1867            json!({"Enum": [{"Accounts":{"Account":"<AccountAddress>"}}]}),
1868            schema.to_json_template()
1869        );
1870    }
1871
1872    /// Tests schema template display in JSON of a Duration
1873    #[test]
1874    fn test_schema_template_display_duration() {
1875        let schema = Type::Duration;
1876        assert_eq!(json!("<Duration (e.g. `10d 1h 42s`)>"), schema.to_json_template());
1877    }
1878
1879    /// Tests schema template display in JSON of a Timestamp
1880    #[test]
1881    fn test_schema_template_display_timestamp() {
1882        let schema = Type::Timestamp;
1883        assert_eq!(json!("<Timestamp (e.g. `2000-01-01T12:00:00Z`)>"), schema.to_json_template());
1884    }
1885
1886    /// Tests schema template display in JSON of an Struct with Field `None`
1887    #[test]
1888    fn test_schema_template_display_struct_with_none_field() {
1889        let schema = Type::Struct(Fields::None);
1890        assert_eq!(json!([]), schema.to_json_template());
1891    }
1892
1893    /// Tests schema template display in JSON of an Struct with named Fields
1894    #[test]
1895    fn test_schema_template_display_struct_with_named_fields() {
1896        let schema = Type::Struct(Fields::Named(Vec::from([(
1897            String::from("Account"),
1898            Type::AccountAddress,
1899        )])));
1900        assert_eq!(json!({"Account":"<AccountAddress>"}), schema.to_json_template());
1901    }
1902
1903    /// Tests schema template display in JSON of a ContractName
1904    #[test]
1905    fn test_schema_template_display_contract_name() {
1906        let schema = Type::ContractName(schema_json::SizeLength::U8);
1907        assert_eq!(json!({"contract":"<String>"}), schema.to_json_template());
1908    }
1909
1910    /// Tests schema template display in JSON of a ReceiveName
1911    #[test]
1912    fn test_schema_template_display_receive_name() {
1913        let schema = Type::ReceiveName(schema_json::SizeLength::U8);
1914        assert_eq!(json!({"contract":"<String>","func":"<String>"}), schema.to_json_template());
1915    }
1916
1917    /// Tests schema template display in JSON of a Map
1918    #[test]
1919    fn test_schema_template_display_map() {
1920        let schema = Type::Map(
1921            schema_json::SizeLength::U8,
1922            Box::new(Type::U8),
1923            Box::new(Type::AccountAddress),
1924        );
1925        assert_eq!(json!([["<UInt8>", "<AccountAddress>"]]), schema.to_json_template());
1926    }
1927
1928    /// Tests schema template display in JSON of a Set
1929    #[test]
1930    fn test_schema_template_display_set() {
1931        let schema = Type::Set(schema_json::SizeLength::U8, Box::new(Type::U8));
1932        assert_eq!(json!(["<UInt8>"]), schema.to_json_template());
1933    }
1934
1935    /// Tests schema template display in JSON of a List
1936    #[test]
1937    fn test_schema_template_display_list() {
1938        let schema = Type::List(schema_json::SizeLength::U8, Box::new(Type::U8));
1939        assert_eq!(json!(["<UInt8>"]), schema.to_json_template());
1940    }
1941
1942    /// Tests schema template display in JSON of an Array
1943    #[test]
1944    fn test_schema_template_display_array() {
1945        let schema = Type::Array(4, Box::new(Type::U8));
1946        assert_eq!(json!(["<UInt8>", "<UInt8>", "<UInt8>", "<UInt8>"]), schema.to_json_template());
1947    }
1948
1949    /// Tests schema template display in JSON of a Pair
1950    #[test]
1951    fn test_schema_template_display_pair() {
1952        let schema = Type::Pair(Box::new(Type::AccountAddress), Box::new(Type::U8));
1953        assert_eq!(json!(("<AccountAddress>", "<UInt8>")), schema.to_json_template());
1954    }
1955
1956    /// Tests schema template display in JSON of an ContractAddress
1957    #[test]
1958    fn test_schema_template_display_contract_address() {
1959        let schema = Type::ContractAddress;
1960        assert_eq!(
1961            json!({"index":"<UInt64>",
1962            "subindex":"<UInt64>"}),
1963            schema.to_json_template()
1964        );
1965    }
1966
1967    /// Tests schema template display in JSON of a Unit
1968    #[test]
1969    fn test_schema_template_display_unit() {
1970        let schema = Type::Unit;
1971        assert_eq!(json!([]), schema.to_json_template());
1972    }
1973
1974    #[test]
1975    fn test_serial_biguint_0() {
1976        let mut bytes = Vec::new();
1977        serial_biguint(0u8.into(), 1, &mut bytes).expect("Serializing failed");
1978        let expected = Vec::from([0]);
1979        assert_eq!(expected, bytes)
1980    }
1981
1982    #[test]
1983    fn test_serial_biguint_10() {
1984        let mut bytes = Vec::new();
1985        serial_biguint(10u8.into(), 1, &mut bytes).expect("Serializing failed");
1986        let expected = Vec::from([10]);
1987        assert_eq!(expected, bytes)
1988    }
1989
1990    #[test]
1991    fn test_serial_biguint_129() {
1992        let mut bytes = Vec::new();
1993        serial_biguint(129u8.into(), 2, &mut bytes).expect("Serializing failed");
1994        let expected = Vec::from([129, 1]);
1995        assert_eq!(expected, bytes)
1996    }
1997
1998    #[test]
1999    fn test_serial_biguint_u64_max() {
2000        let mut bytes = Vec::new();
2001        serial_biguint(u64::MAX.into(), 10, &mut bytes).expect("Serializing failed");
2002        let expected = Vec::from([255, 255, 255, 255, 255, 255, 255, 255, 255, 1]);
2003        assert_eq!(expected, bytes)
2004    }
2005
2006    #[test]
2007    fn test_serial_biguint_u256_max() {
2008        let u256_max = BigUint::from_bytes_le(&[
2009            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
2010            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
2011        ]);
2012        let mut bytes = Vec::new();
2013        serial_biguint(u256_max, 37, &mut bytes).expect("Serializing failed");
2014        let expected = Vec::from([
2015            255,
2016            255,
2017            255,
2018            255,
2019            255,
2020            255,
2021            255,
2022            255,
2023            255,
2024            255,
2025            255,
2026            255,
2027            255,
2028            255,
2029            255,
2030            255,
2031            255,
2032            255,
2033            255,
2034            255,
2035            255,
2036            255,
2037            255,
2038            255,
2039            255,
2040            255,
2041            255,
2042            255,
2043            255,
2044            255,
2045            255,
2046            255,
2047            255,
2048            255,
2049            255,
2050            255,
2051            0b0000_1111,
2052        ]);
2053        assert_eq!(expected, bytes)
2054    }
2055
2056    #[test]
2057    fn test_serial_biguint_contraint_fails() {
2058        let mut bytes = Vec::new();
2059        serial_biguint(129u8.into(), 1, &mut bytes).expect_err("Serialization should have failed");
2060    }
2061
2062    #[test]
2063    fn test_serial_bigint_0() {
2064        let mut bytes = Vec::new();
2065        serial_bigint(0.into(), 1, &mut bytes).expect("Serializing failed");
2066        let expected = Vec::from([0]);
2067        assert_eq!(expected, bytes)
2068    }
2069
2070    #[test]
2071    fn test_serial_bigint_10() {
2072        let mut bytes = Vec::new();
2073        serial_bigint(10.into(), 1, &mut bytes).expect("Serializing failed");
2074        let expected = Vec::from([10]);
2075        assert_eq!(expected, bytes)
2076    }
2077
2078    #[test]
2079    fn test_serial_bigint_neg_10() {
2080        let mut bytes = Vec::new();
2081        serial_bigint((-10).into(), 1, &mut bytes).expect("Serializing failed");
2082        let expected = Vec::from([0b0111_0110]);
2083        assert_eq!(expected, bytes)
2084    }
2085
2086    #[test]
2087    fn test_serial_bigint_neg_129() {
2088        let mut bytes = Vec::new();
2089        serial_bigint((-129).into(), 2, &mut bytes).expect("Serializing failed");
2090        let expected = Vec::from([0b1111_1111, 0b0111_1110]);
2091        assert_eq!(expected, bytes)
2092    }
2093
2094    #[test]
2095    fn test_serial_bigint_i64_min() {
2096        let mut bytes = Vec::new();
2097        serial_bigint(i64::MIN.into(), 10, &mut bytes).expect("Serializing failed");
2098        let expected = Vec::from([128, 128, 128, 128, 128, 128, 128, 128, 128, 0b0111_1111]);
2099        assert_eq!(expected, bytes)
2100    }
2101
2102    #[test]
2103    fn test_serial_bigint_constraint_fails() {
2104        let mut bytes = Vec::new();
2105        serial_bigint(i64::MIN.into(), 2, &mut bytes).expect_err("Deserialising should fail");
2106    }
2107
2108    /// Tests that attempting to serialize a valid byte sequence as
2109    /// [`Type::AccountAddress`] succeeds.
2110    #[test]
2111    fn test_serial_account_address() {
2112        let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
2113        let account = AccountAddress(account_bytes);
2114        let schema = Type::AccountAddress;
2115        let bytes =
2116            schema.serial_value(&json!(format!("{}", &account))).expect("Serializing failed");
2117
2118        let expected = Vec::from(account_bytes);
2119        assert_eq!(expected, bytes)
2120    }
2121
2122    /// Tests that attempting to serialize an invalid byte sequence as
2123    /// [`Type::AccountAddress`] fails with expected error type.
2124    #[test]
2125    fn test_serial_account_address_wrong_address_fails() {
2126        let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
2127        let account = AccountAddress(account_bytes);
2128        let schema = Type::AccountAddress;
2129        let json = json!(format!("{}", &account).get(1..));
2130        let err = schema.serial_value(&json).expect_err("Serializing should fail");
2131
2132        assert!(matches!(err, JsonError::FailedParsingAccountAddress))
2133    }
2134
2135    /// Tests that attempting to serialize a non-[`AccountAddress`] value with
2136    /// [`Type::AccountAddress`] schema results in error of expected type.
2137    #[test]
2138    fn test_serial_account_wrong_type_fails() {
2139        let schema = Type::AccountAddress;
2140        let json = json!(123);
2141        let err = schema.serial_value(&json).expect_err("Serializing should fail");
2142
2143        assert!(matches!(err, JsonError::WrongJsonType(_)))
2144    }
2145
2146    /// Tests that attempting to serialize a malformed value wrapped in a
2147    /// [`Type::List`] results in a nested error with trace information in the
2148    /// wrapping layer.
2149    #[test]
2150    fn test_serial_list_fails_with_trace() {
2151        let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
2152        let account = AccountAddress(account_bytes);
2153        let schema = Type::List(SizeLength::U8, Box::new(Type::AccountAddress));
2154        let json = json!([format!("{}", account), 123]);
2155        let err = schema.serial_value(&json).expect_err("Serializing should fail");
2156
2157        assert!(matches!(
2158            err,
2159            JsonError::TraceError {
2160                field,
2161                error,
2162                ..
2163            } if matches!(*error, JsonError::WrongJsonType(_)) && field == "1"
2164        ));
2165    }
2166
2167    /// Tests that attempting to serialize a malformed value wrapped in a
2168    /// [`Type::Struct`] results in a nested error with trace information in the
2169    /// wrapping layer.
2170    #[test]
2171    fn test_serial_object_fails_with_trace() {
2172        let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
2173        let account = AccountAddress(account_bytes);
2174        let schema = Type::Struct(Fields::Named(vec![
2175            ("account".into(), Type::AccountAddress),
2176            ("contract".into(), Type::ContractAddress),
2177        ]));
2178        let json = json!({ "account": format!("{}", account), "contract": {} });
2179        let err = schema.serial_value(&json).expect_err("Serializing should fail");
2180
2181        assert!(matches!(
2182            err,
2183            JsonError::TraceError {
2184                field,
2185                error,
2186                ..
2187            } if matches!(*error, JsonError::FieldError(_)) && field == "\"contract\""
2188        ));
2189    }
2190
2191    /// Tests that attempting to serialize a malformed value wrapped in multiple
2192    /// layers results in a nested error with trace information in the
2193    /// wrapping layers.
2194    #[test]
2195    fn test_serial_fails_with_nested_trace() {
2196        let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
2197        let account = AccountAddress(account_bytes);
2198        let schema_object = Type::Struct(Fields::Named(vec![
2199            ("account".into(), Type::AccountAddress),
2200            ("contract".into(), Type::ContractAddress),
2201        ]));
2202        let schema = Type::List(SizeLength::U8, Box::new(schema_object));
2203        let json = json!([{ "account": format!("{}", account), "contract": { "index": 0, "subindex": 0} }, { "account": format!("{}", account), "contract": {} }]);
2204        let err = schema.serial_value(&json).expect_err("Serializing should fail");
2205
2206        assert!(matches!(
2207            err,
2208            JsonError::TraceError {
2209                field,
2210                error,
2211                ..
2212            } if field == "1" && matches!(
2213                *error.clone(),
2214                JsonError::TraceError {
2215                    field,
2216                    error,
2217                    ..
2218                } if field == "\"contract\"" && matches!(*error, JsonError::FieldError(_))
2219            )
2220        ));
2221    }
2222
2223    #[test]
2224    fn test_deserial_biguint_0() {
2225        let mut cursor = Cursor::new([0]);
2226        let int = deserial_biguint(&mut cursor, 1).expect("Deserialising should not fail");
2227        assert_eq!(int, 0u8.into())
2228    }
2229
2230    #[test]
2231    fn test_deserial_biguint_10() {
2232        let mut cursor = Cursor::new([10]);
2233        let int = deserial_biguint(&mut cursor, 1).expect("Deserialising should not fail");
2234        assert_eq!(int, 10u8.into())
2235    }
2236
2237    #[test]
2238    fn test_deserial_biguint_129() {
2239        let mut cursor = Cursor::new([129, 1]);
2240        let int = deserial_biguint(&mut cursor, 2).expect("Deserialising should not fail");
2241        assert_eq!(int, 129u8.into())
2242    }
2243
2244    #[test]
2245    fn test_deserial_biguint_u64_max() {
2246        let mut cursor = Cursor::new([255, 255, 255, 255, 255, 255, 255, 255, 255, 1]);
2247        let int = deserial_biguint(&mut cursor, 10).expect("Deserialising should not fail");
2248        assert_eq!(int, u64::MAX.into())
2249    }
2250
2251    #[test]
2252    fn test_deserial_biguint_u256_max() {
2253        let mut cursor = Cursor::new([
2254            255,
2255            255,
2256            255,
2257            255,
2258            255,
2259            255,
2260            255,
2261            255,
2262            255,
2263            255,
2264            255,
2265            255,
2266            255,
2267            255,
2268            255,
2269            255,
2270            255,
2271            255,
2272            255,
2273            255,
2274            255,
2275            255,
2276            255,
2277            255,
2278            255,
2279            255,
2280            255,
2281            255,
2282            255,
2283            255,
2284            255,
2285            255,
2286            255,
2287            255,
2288            255,
2289            255,
2290            0b0000_1111,
2291        ]);
2292        let int = deserial_biguint(&mut cursor, 37).expect("Deserialising should not fail");
2293        let u256_max = BigUint::from_bytes_le(&[
2294            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
2295            255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
2296        ]);
2297        assert_eq!(int, u256_max)
2298    }
2299
2300    #[test]
2301    fn test_deserial_biguint_padding_allowed() {
2302        let mut cursor = Cursor::new([129, 128, 128, 128, 128, 0]);
2303        let int = deserial_biguint(&mut cursor, 6).expect("Deserialising should not fail");
2304        assert_eq!(int, 1u8.into())
2305    }
2306
2307    #[test]
2308    fn test_deserial_biguint_contraint_fails() {
2309        let mut cursor = Cursor::new([129, 1]);
2310        deserial_biguint(&mut cursor, 1).expect_err("Deserialising should fail");
2311    }
2312
2313    #[test]
2314    fn test_deserial_bigint_0() {
2315        let mut cursor = Cursor::new([0]);
2316        let int = deserial_bigint(&mut cursor, 1).expect("Deserialising should not fail");
2317        assert_eq!(int, 0u8.into())
2318    }
2319
2320    #[test]
2321    fn test_deserial_bigint_10() {
2322        let mut cursor = Cursor::new([10]);
2323        let int = deserial_bigint(&mut cursor, 1).expect("Deserialising should not fail");
2324        assert_eq!(int, 10u8.into())
2325    }
2326
2327    #[test]
2328    fn test_deserial_bigint_neg_10() {
2329        let mut cursor = Cursor::new([0b0111_0110]);
2330        let int = deserial_bigint(&mut cursor, 2).expect("Deserialising should not fail");
2331        assert_eq!(int, (-10).into())
2332    }
2333
2334    #[test]
2335    fn test_deserial_bigint_neg_129() {
2336        let mut cursor = Cursor::new([0b1111_1111, 0b0111_1110]);
2337        let int = deserial_bigint(&mut cursor, 3).expect("Deserialising should not fail");
2338        assert_eq!(int, (-129).into())
2339    }
2340
2341    #[test]
2342    fn test_deserial_bigint_i64_min() {
2343        let mut cursor = Cursor::new([128, 128, 128, 128, 128, 128, 128, 128, 128, 0b0111_1111]);
2344        let int = deserial_bigint(&mut cursor, 10).expect("Deserialising should not fail");
2345        assert_eq!(int, BigInt::from(i64::MIN))
2346    }
2347
2348    #[test]
2349    fn test_deserial_bigint_constraint_fails() {
2350        let mut cursor = Cursor::new([128, 128, 128, 128, 128, 128, 128, 128, 128, 0b0111_1111]);
2351        deserial_bigint(&mut cursor, 9).expect_err("Deserialising should fail");
2352    }
2353
2354    /// Tests that attempting to deserialize a valid byte sequence using
2355    /// [`Type::AccountAddress`] succeeds and results in the expected JSON
2356    /// format.
2357    #[test]
2358    fn test_deserial_account_address() {
2359        let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
2360        let mut cursor = Cursor::new(&account_bytes);
2361        let schema = Type::AccountAddress;
2362        let value = schema.to_json(&mut cursor).expect("Deserializing should not fail");
2363
2364        let expected = json!(format!("{}", AccountAddress(account_bytes)));
2365        assert_eq!(expected, value)
2366    }
2367
2368    /// Tests that attempting to deserialize a non-[`AccountAddress`] value with
2369    /// [`Type::AccountAddress`] schema results in an error of expected format.
2370    #[test]
2371    fn test_deserial_malformed_account_address_fails() {
2372        let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
2373        let mut cursor = Cursor::new(&account_bytes[..30]); // Malformed account address
2374        let schema = Type::AccountAddress;
2375        let err = schema.to_json(&mut cursor).expect_err("Deserializing should fail");
2376
2377        assert!(matches!(err, ToJsonError::DeserialError {
2378            position: 0,
2379            schema: Type::AccountAddress,
2380            ..
2381        }))
2382    }
2383
2384    /// Tests that attempting to deserialize a malformed value wrapped in a
2385    /// [`Type::List`] fails with a nested error.
2386    #[test]
2387    fn test_deserial_malformed_list_fails() {
2388        let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
2389        let mut list_bytes = vec![2, 0];
2390        list_bytes.extend_from_slice(&account_bytes);
2391        list_bytes.extend_from_slice(&account_bytes[..30]); // Malformed account address
2392
2393        let mut cursor = Cursor::new(list_bytes);
2394        let schema = Type::List(SizeLength::U8, Box::new(Type::AccountAddress));
2395        let err = schema.to_json(&mut cursor).expect_err("Deserializing should fail");
2396
2397        assert!(matches!(
2398            err,
2399            ToJsonError::TraceError {
2400                position: 0,
2401                schema: Type::List(_, _),
2402                error,
2403            } if matches!(
2404                *error,
2405                ToJsonError::DeserialError {
2406                    position: 33,
2407                    schema: Type::AccountAddress, ..
2408                }
2409            )
2410        ))
2411    }
2412
2413    /// Tests that attempting to deserialize a malformed value wrapped in
2414    /// multiple layers fails with a nested error with wrapping layers
2415    /// corresponding to the layers wrapping the malformed value.
2416    #[test]
2417    fn test_deserial_malformed_nested_list_fails() {
2418        let account_bytes = [0u8; ACCOUNT_ADDRESS_SIZE];
2419        let contract_bytes = [0u8; 16];
2420        let mut list_bytes = vec![2, 0];
2421        list_bytes.extend_from_slice(&account_bytes);
2422        list_bytes.extend_from_slice(&contract_bytes);
2423        list_bytes.extend_from_slice(&account_bytes);
2424        list_bytes.extend_from_slice(&contract_bytes[..10]); // Malformed contract address.
2425
2426        let mut cursor = Cursor::new(list_bytes);
2427        let schema_object = Type::Struct(Fields::Named(vec![
2428            ("a".into(), Type::AccountAddress),
2429            ("b".into(), Type::ContractAddress),
2430        ]));
2431        let schema = Type::List(SizeLength::U8, Box::new(schema_object));
2432        let err = schema.to_json(&mut cursor).expect_err("Deserializing should fail");
2433
2434        assert!(matches!(
2435            err,
2436            ToJsonError::TraceError {
2437                position: 0,
2438                schema: Type::List(_,_),
2439                error,
2440            } if matches!(
2441                *error.clone(),
2442                ToJsonError::TraceError {
2443                    position: 49,
2444                    schema: Type::Struct(_),
2445                    error
2446                } if matches!(
2447                    *error,
2448                    ToJsonError::DeserialError {
2449                        position: 81,
2450                        schema: Type::ContractAddress,
2451                        ..
2452                    }
2453                )
2454            )
2455        ))
2456    }
2457}
2458
2459impl Fields {
2460    pub fn to_json<T: AsRef<[u8]>>(
2461        &self,
2462        source: &mut Cursor<T>,
2463    ) -> Result<serde_json::Value, ToJsonError> {
2464        use serde_json::*;
2465
2466        match self {
2467            Fields::Named(fields) => {
2468                let mut values = map::Map::new();
2469                for (key, ty) in fields.iter() {
2470                    let value = ty.to_json(source)?;
2471                    values.insert(key.to_string(), value);
2472                }
2473                Ok(Value::Object(values))
2474            }
2475            Fields::Unnamed(fields) => {
2476                let mut values = Vec::new();
2477                for ty in fields.iter() {
2478                    values.push(ty.to_json(source)?);
2479                }
2480                Ok(Value::Array(values))
2481            }
2482            Fields::None => Ok(Value::Array(Vec::new())),
2483        }
2484    }
2485}
2486
2487impl From<std::string::FromUtf8Error> for ParseError {
2488    fn from(_: std::string::FromUtf8Error) -> Self { ParseError::default() }
2489}
2490
2491/// Deserialize a list of values corresponding to the `item_to_json` function
2492/// from `source`
2493fn item_list_to_json<T: AsRef<[u8]>>(
2494    source: &mut Cursor<T>,
2495    size_len: SizeLength,
2496    item_to_json: impl Fn(&mut Cursor<T>) -> Result<serde_json::Value, ToJsonError>,
2497    schema: &Type,
2498) -> Result<Vec<serde_json::Value>, ToJsonError> {
2499    let data = source.data.as_ref().to_owned().into();
2500    let position = source.cursor_position();
2501    let len = deserial_length(source, size_len).map_err(|_| ToJsonError::DeserialError {
2502        data,
2503        position,
2504        reason: "Could not deserialize length of list".into(),
2505        schema: schema.clone(),
2506    })?;
2507    let mut values = Vec::with_capacity(std::cmp::min(MAX_PREALLOCATED_CAPACITY, len));
2508    for _ in 0..len {
2509        let value = item_to_json(source)?;
2510        values.push(value);
2511    }
2512    Ok(values)
2513}
2514
2515/// Deserialize a [`String`] of variable length from `source`.
2516fn deserial_string<R: Read>(
2517    source: &mut R,
2518    size_len: SizeLength,
2519) -> Result<String, ParseErrorWithReason> {
2520    let len = deserial_length(source, size_len)
2521        .map_err(|_| ParseErrorWithReason("Could not parse String length".into()))?;
2522    // we are doing this case analysis so that we have a fast path for safe,
2523    // most common, lengths, and a slower one longer ones.
2524    if len <= MAX_PREALLOCATED_CAPACITY {
2525        let mut bytes = vec![0u8; len];
2526        source.read_exact(&mut bytes).map_err(|_| {
2527            ParseErrorWithReason(format!(
2528                "Parsed length {} for String value, but failed to read {} bytes from value",
2529                len, len
2530            ))
2531        })?;
2532        Ok(String::from_utf8(bytes)
2533            .map_err(|_| ParseErrorWithReason("Failed to deserialize String from value".into()))?)
2534    } else {
2535        let mut bytes: Vec<u8> = Vec::with_capacity(MAX_PREALLOCATED_CAPACITY);
2536        let mut buf = [0u8; 64];
2537        let mut read = 0;
2538        while read < len {
2539            let new = source.read(&mut buf).map_err(|_| {
2540                let end = std::cmp::min(len - read, 64);
2541                ParseErrorWithReason(format!(
2542                    "Parsed length {} for String value, but failed to read bytes {}..{} from value",
2543                    len,
2544                    read,
2545                    read + end
2546                ))
2547            })?;
2548            if new == 0 {
2549                break;
2550            } else {
2551                read += new;
2552                bytes.extend_from_slice(&buf[..new]);
2553            }
2554        }
2555        if read == len {
2556            Ok(String::from_utf8(bytes).map_err(|_| {
2557                ParseErrorWithReason("Failed to deserialize String from value".into())
2558            })?)
2559        } else {
2560            Err(ParseErrorWithReason(format!(
2561                "Parsed length {} for String value, but unexpectedly read {} bytes",
2562                len, read
2563            )))
2564        }
2565    }
2566}
2567
2568impl Type {
2569    /// Uses the schema to deserialize bytes into pretty json
2570    pub fn to_json_string_pretty(&self, bytes: &[u8]) -> Result<String, ToJsonError> {
2571        let source = &mut Cursor::new(bytes);
2572        let js = self.to_json(source)?;
2573        serde_json::to_string_pretty(&js).map_err(|_| ToJsonError::FormatError {})
2574    }
2575
2576    /// Uses the schema to deserialize bytes into json
2577    pub fn to_json<T: AsRef<[u8]>>(
2578        &self,
2579        source: &mut Cursor<T>,
2580    ) -> Result<serde_json::Value, ToJsonError> {
2581        use serde_json::*;
2582
2583        let data = source.data.as_ref().to_owned().into();
2584        let position = source.cursor_position();
2585
2586        let deserial_error = |reason: String| ToJsonError::DeserialError {
2587            data,
2588            position,
2589            reason,
2590            schema: self.clone(),
2591        };
2592
2593        match self {
2594            Type::Unit => Ok(Value::Null),
2595            Type::Bool => {
2596                let n = bool::deserial(source).map_err(|_| {
2597                    deserial_error(
2598                        "Could not parse bool from value, expected a byte containing the value 0 \
2599                         or 1"
2600                            .into(),
2601                    )
2602                })?;
2603                Ok(Value::Bool(n))
2604            }
2605            Type::U8 => {
2606                let n = u8::deserial(source).map_err(|_| {
2607                    deserial_error(
2608                        "Could not parse u8 from value as not enough data was available (needs 1 \
2609                         byte)"
2610                            .into(),
2611                    )
2612                })?;
2613                Ok(Value::Number(n.into()))
2614            }
2615            Type::U16 => {
2616                let n = u16::deserial(source).map_err(|_| {
2617                    deserial_error(
2618                        "Could not parse u16 from value as not enough data was available (needs 2 \
2619                         bytes)"
2620                            .into(),
2621                    )
2622                })?;
2623                Ok(Value::Number(n.into()))
2624            }
2625            Type::U32 => {
2626                let n = u32::deserial(source).map_err(|_| {
2627                    deserial_error(
2628                        "Could not parse u32 from value as not enough data was available (needs 4 \
2629                         bytes)"
2630                            .into(),
2631                    )
2632                })?;
2633                Ok(Value::Number(n.into()))
2634            }
2635            Type::U64 => {
2636                let n = u64::deserial(source).map_err(|_| {
2637                    deserial_error(
2638                        "Could not parse u64 from value as not enough data was available (needs 8 \
2639                         bytes)"
2640                            .into(),
2641                    )
2642                })?;
2643                Ok(Value::Number(n.into()))
2644            }
2645            Type::U128 => {
2646                let n = u128::deserial(source).map_err(|_| {
2647                    deserial_error(
2648                        "Could not parse u128 from value as not enough data was available (needs \
2649                         16 bytes)"
2650                            .into(),
2651                    )
2652                })?;
2653                Ok(Value::String(n.to_string()))
2654            }
2655            Type::I8 => {
2656                let n = i8::deserial(source).map_err(|_| {
2657                    deserial_error(
2658                        "Could not parse i8 from value as not enough data was available (needs 1 \
2659                         byte)"
2660                            .into(),
2661                    )
2662                })?;
2663                Ok(Value::Number(n.into()))
2664            }
2665            Type::I16 => {
2666                let n = i16::deserial(source).map_err(|_| {
2667                    deserial_error(
2668                        "Could not parse i16 from value as not enough data was available (needs 2 \
2669                         bytes)"
2670                            .into(),
2671                    )
2672                })?;
2673                Ok(Value::Number(n.into()))
2674            }
2675            Type::I32 => {
2676                let n = i32::deserial(source).map_err(|_| {
2677                    deserial_error(
2678                        "Could not parse i32 from value as not enough data was available (needs 4 \
2679                         bytes)"
2680                            .into(),
2681                    )
2682                })?;
2683                Ok(Value::Number(n.into()))
2684            }
2685            Type::I64 => {
2686                let n = i64::deserial(source).map_err(|_| {
2687                    deserial_error(
2688                        "Could not parse i64 from value as not enough data was available (needs 8 \
2689                         bytes)"
2690                            .into(),
2691                    )
2692                })?;
2693                Ok(Value::Number(n.into()))
2694            }
2695            Type::I128 => {
2696                let n = i128::deserial(source).map_err(|_| {
2697                    deserial_error(
2698                        "Could not parse i128 from value as not enough data was available (needs \
2699                         16 bytes)"
2700                            .into(),
2701                    )
2702                })?;
2703                Ok(Value::String(n.to_string()))
2704            }
2705            Type::Amount => {
2706                let n = Amount::deserial(source).map_err(|_| {
2707                    deserial_error(
2708                        "Could not parse Amount from value as not enough data was available \
2709                         (needs 8 bytes)"
2710                            .into(),
2711                    )
2712                })?;
2713                Ok(Value::String(n.micro_ccd().to_string()))
2714            }
2715            Type::AccountAddress => {
2716                let address = AccountAddress::deserial(source).map_err(|_| {
2717                    deserial_error(
2718                        "Could not parse AccountAddress from value as not enough data was \
2719                         available (needs 32 bytes)"
2720                            .into(),
2721                    )
2722                })?;
2723                Ok(Value::String(address.to_string()))
2724            }
2725            Type::ContractAddress => {
2726                let address = ContractAddress::deserial(source).map_err(|_| {
2727                    deserial_error(
2728                        "Could not parse ContractAddress from value as not enough data was \
2729                         available (needs 16 bytes)"
2730                            .into(),
2731                    )
2732                })?;
2733                Ok(serde_json::to_value(address).map_err(|_| ToJsonError::FormatError {})?)
2734            }
2735            Type::Timestamp => {
2736                let timestamp = Timestamp::deserial(source).map_err(|_| {
2737                    deserial_error(
2738                        "Could not parse Timestamp from value as not enough data was available \
2739                         (needs 8 bytes)"
2740                            .into(),
2741                    )
2742                })?;
2743                Ok(Value::String(timestamp.to_string()))
2744            }
2745            Type::Duration => {
2746                let duration = Duration::deserial(source).map_err(|_| {
2747                    deserial_error(
2748                        "Could not parse Duration from value as not enough data was available \
2749                         (needs 8 bytes)"
2750                            .into(),
2751                    )
2752                })?;
2753                Ok(Value::String(duration.to_string()))
2754            }
2755            Type::Pair(left_type, right_type) => {
2756                let left = left_type.to_json(source).map_err(|e| e.add_trace(position, self))?;
2757                let right = right_type.to_json(source).map_err(|e| e.add_trace(position, self))?;
2758                Ok(Value::Array(vec![left, right]))
2759            }
2760            Type::List(size_len, ty) => {
2761                let values = item_list_to_json(source, *size_len, |s| ty.to_json(s), self)
2762                    .map_err(|e| e.add_trace(position, self))?;
2763                Ok(Value::Array(values))
2764            }
2765            Type::Set(size_len, ty) => {
2766                let values = item_list_to_json(source, *size_len, |s| ty.to_json(s), self)
2767                    .map_err(|e| e.add_trace(position, self))?;
2768                Ok(Value::Array(values))
2769            }
2770            Type::Map(size_len, key_type, value_type) => {
2771                let values = item_list_to_json(
2772                    source,
2773                    *size_len,
2774                    |s| {
2775                        let key = key_type.to_json(s).map_err(|e| e.add_trace(position, self))?;
2776                        let value =
2777                            value_type.to_json(s).map_err(|e| e.add_trace(position, self))?;
2778                        Ok(Value::Array(vec![key, value]))
2779                    },
2780                    self,
2781                )?;
2782                Ok(Value::Array(values))
2783            }
2784            Type::Array(len, ty) => {
2785                let len: usize = (*len).try_into().map_err(|_| {
2786                    deserial_error("Could not parse Array length from value".into())
2787                })?;
2788                let mut values = Vec::with_capacity(std::cmp::min(MAX_PREALLOCATED_CAPACITY, len));
2789                for _ in 0..len {
2790                    let value = ty.to_json(source).map_err(|e| e.add_trace(position, self))?;
2791                    values.push(value);
2792                }
2793                Ok(Value::Array(values))
2794            }
2795            Type::Struct(fields_ty) => {
2796                let fields = fields_ty.to_json(source).map_err(|e| e.add_trace(position, self))?;
2797                Ok(fields)
2798            }
2799            Type::Enum(variants) => {
2800                let idx = if variants.len() <= 256 {
2801                    u8::deserial(source).map(|v| v as usize).map_err(|_| {
2802                        ParseErrorWithReason(
2803                            "Could not parse Enum id as u8 from value (needs 1 byte)".into(),
2804                        )
2805                    })
2806                } else {
2807                    u16::deserial(source).map(|v| v as usize).map_err(|_| {
2808                        ParseErrorWithReason(
2809                            "Could not parse Enum id as u16 from value (needs 2 bytes)".into(),
2810                        )
2811                    })
2812                };
2813                let variant = idx.and_then(|idx| {
2814                    variants.get(idx).ok_or_else(|| {
2815                        ParseErrorWithReason(format!("Could not find Enum variant with id {}", idx))
2816                    })
2817                });
2818
2819                // Map all error cases into the same error.
2820                match variant {
2821                    Ok((name, fields_ty)) => {
2822                        let fields =
2823                            fields_ty.to_json(source).map_err(|e| e.add_trace(position, self))?;
2824                        Ok(json!({ name: fields }))
2825                    }
2826                    Err(e) => Err(deserial_error(e.0)),
2827                }
2828            }
2829            Type::TaggedEnum(variants) => {
2830                let idx = u8::deserial(source).map_err(|_| {
2831                    ParseErrorWithReason(
2832                        "Could not parse TaggedEnum id from value (needs 1 byte)".into(),
2833                    )
2834                });
2835                let variant = idx.and_then(|idx| {
2836                    variants.get(&idx).ok_or_else(|| {
2837                        ParseErrorWithReason(format!(
2838                            "Could not find TaggedEnum variant with id {}",
2839                            idx
2840                        ))
2841                    })
2842                });
2843
2844                match variant {
2845                    Ok((name, fields_ty)) => {
2846                        let fields =
2847                            fields_ty.to_json(source).map_err(|e| e.add_trace(position, self))?;
2848                        Ok(json!({ name: fields }))
2849                    }
2850                    Err(e) => Err(deserial_error(e.0)),
2851                }
2852            }
2853            Type::String(size_len) => {
2854                let string = deserial_string(source, *size_len).map_err(|e| deserial_error(e.0))?;
2855                Ok(Value::String(string))
2856            }
2857            Type::ContractName(size_len) => {
2858                let name = deserial_string(source, *size_len).map_err(|e| {
2859                    ParseErrorWithReason(format!(
2860                        "Could not parse contract name from value ({})",
2861                        e
2862                    ))
2863                });
2864                let owned_contract_name = name.and_then(|n| {
2865                    OwnedContractName::new(n)
2866                        .map_err(|e| ParseErrorWithReason(format!("Invalid contract name ({})", e)))
2867                });
2868
2869                owned_contract_name
2870                    .map(|ocn| {
2871                        let name_without_init = ocn.as_contract_name().contract_name();
2872                        json!({ "contract": name_without_init })
2873                    })
2874                    .map_err(|e| deserial_error(e.0))
2875            }
2876            Type::ReceiveName(size_len) => {
2877                let name = deserial_string(source, *size_len).map_err(|e| {
2878                    ParseErrorWithReason(format!("Could not parse receive name from value ({})", e))
2879                });
2880                let owned_receive_name = name.and_then(|n| {
2881                    OwnedReceiveName::new(n)
2882                        .map_err(|e| ParseErrorWithReason(format!("Invalid receive name ({})", e)))
2883                });
2884
2885                owned_receive_name
2886                    .map(|orn| {
2887                        let receive_name = orn.as_receive_name();
2888                        let contract_name = receive_name.contract_name();
2889                        let func_name = receive_name.entrypoint_name();
2890                        json!({"contract": contract_name, "func": func_name})
2891                    })
2892                    .map_err(|e| deserial_error(e.0))
2893            }
2894            Type::ULeb128(constraint) => {
2895                let int = deserial_biguint(source, *constraint).map_err(|_| {
2896                    deserial_error("Could not parse unsigned integer (uleb128) from value".into())
2897                })?;
2898                Ok(Value::String(int.to_string()))
2899            }
2900            Type::ILeb128(constraint) => {
2901                let int = deserial_bigint(source, *constraint).map_err(|_| {
2902                    deserial_error("Could not parse signed integer (leb128) from value".into())
2903                })?;
2904                Ok(Value::String(int.to_string()))
2905            }
2906            Type::ByteList(size_len) => {
2907                let len = deserial_length(source, *size_len).map_err(|_| {
2908                    ParseErrorWithReason("Could not parse ByteList length from value".into())
2909                });
2910                let bytes: core::result::Result<Vec<_>, _> =
2911                    len.as_ref().map_err(|e| e.clone()).and_then(|len| {
2912                        let mut bytes =
2913                            Vec::with_capacity(std::cmp::min(MAX_PREALLOCATED_CAPACITY, *len));
2914
2915                        for i in 0..*len {
2916                            let byte = source.read_u8().map_err(|_| {
2917                                ParseErrorWithReason(format!(
2918                                    "Failed to read byte {} of ByteList value",
2919                                    i
2920                                ))
2921                            });
2922                            bytes.push(byte);
2923                        }
2924
2925                        bytes.into_iter().collect()
2926                    });
2927
2928                match (len, bytes) {
2929                    (Ok(len), Ok(bytes)) => {
2930                        let mut string = String::with_capacity(std::cmp::min(
2931                            MAX_PREALLOCATED_CAPACITY,
2932                            2 * len,
2933                        ));
2934                        string.push_str(&hex::encode(bytes));
2935                        Ok(Value::String(string))
2936                    }
2937                    (Err(e), _) => Err(deserial_error(e.0)),
2938                    (_, Err(e)) => Err(deserial_error(e.0)),
2939                }
2940            }
2941            Type::ByteArray(len) => {
2942                let len = usize::try_from(*len).map_err(|_| {
2943                    ParseErrorWithReason("Could not parse ByteArray length from value".into())
2944                });
2945                let bytes: core::result::Result<Vec<_>, _> =
2946                    len.as_ref().map_err(|e| e.clone()).and_then(|len| {
2947                        let mut bytes =
2948                            Vec::with_capacity(std::cmp::min(MAX_PREALLOCATED_CAPACITY, *len));
2949
2950                        for i in 0..*len {
2951                            let byte = source.read_u8().map_err(|_| {
2952                                ParseErrorWithReason(format!(
2953                                    "Failed to read byte {} of ByteArray value",
2954                                    i
2955                                ))
2956                            });
2957                            bytes.push(byte);
2958                        }
2959
2960                        bytes.into_iter().collect()
2961                    });
2962
2963                match (len, bytes) {
2964                    (Ok(len), Ok(bytes)) => {
2965                        let mut string = String::with_capacity(std::cmp::min(
2966                            MAX_PREALLOCATED_CAPACITY,
2967                            2 * len,
2968                        ));
2969                        string.push_str(&hex::encode(bytes));
2970                        Ok(Value::String(string))
2971                    }
2972                    (Err(e), _) => Err(deserial_error(e.0)),
2973                    (_, Err(e)) => Err(deserial_error(e.0)),
2974                }
2975            }
2976        }
2977    }
2978}
2979
2980/// Deserialize a uleb128 encoded [`BigUint`] from `source`.
2981fn deserial_biguint<R: Read>(source: &mut R, constraint: u32) -> ParseResult<BigUint> {
2982    let mut result = BigUint::zero();
2983    let mut shift = 0;
2984    for _ in 0..constraint {
2985        let byte = source.read_u8()?;
2986        let value_byte = BigUint::from(byte & 0b0111_1111);
2987        result += value_byte << shift;
2988        shift += 7;
2989
2990        if byte & 0b1000_0000 == 0 {
2991            return Ok(result);
2992        }
2993    }
2994    Err(ParseError {})
2995}
2996
2997/// Deserialize a ileb128 encoded [`BigInt`] from `source`.
2998fn deserial_bigint<R: Read>(source: &mut R, constraint: u32) -> ParseResult<BigInt> {
2999    let mut result = BigInt::zero();
3000    let mut shift = 0;
3001    for _ in 0..constraint {
3002        let byte = source.read_u8()?;
3003        let value_byte = BigInt::from(byte & 0b0111_1111);
3004        result += value_byte << shift;
3005        shift += 7;
3006
3007        if byte & 0b1000_0000 == 0 {
3008            if byte & 0b0100_0000 != 0 {
3009                result -= BigInt::from(2).pow(shift)
3010            }
3011            return Ok(result);
3012        }
3013    }
3014    Err(ParseError {})
3015}