1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use std::{ops::Deref, str::FromStr};

use cairo_felt::Felt252;
use cairo_lang_runner::Arg;
use serde::{de::Visitor, Deserialize};
use serde_json::Value;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum VecArgError {
    #[error("failed to parse array")]
    ArrayParseError,
    #[error("failed to parse number: {0}")]
    NumberParseError(#[from] std::num::ParseIntError),
    #[error("failed to parse bigint: {0}")]
    BigIntParseError(#[from] num_bigint::ParseBigIntError),
    #[error("number out of range")]
    NumberOutOfRange,
}

/// `VecArg` is a wrapper around a vector of `Arg`.
///
/// It provides convenience methods for working with a vector of `Arg` and implements
/// `Deref` to allow it to be treated like a vector of `Arg`.
#[derive(Debug)]
pub struct VecArg(Vec<Arg>);

impl VecArg {
    /// Creates a new `VecArg` from a vector of `Arg`.
    ///
    /// # Arguments
    ///
    /// * `VecArg` - A vector of `Arg`.
    ///
    /// # Returns
    ///
    /// * `VecArg` - A new `VecArg` instance.
    #[must_use]
    pub fn new(args: Vec<Arg>) -> Self {
        Self(args)
    }
}

impl Deref for VecArg {
    type Target = Vec<Arg>;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl From<VecArg> for Vec<Arg> {
    fn from(args: VecArg) -> Self {
        args.0
    }
}

impl From<Vec<Arg>> for VecArg {
    fn from(args: Vec<Arg>) -> Self {
        Self(args)
    }
}

impl VecArg {
    fn visit_seq_helper(seq: &[Value]) -> Result<Self, VecArgError> {
        let iterator = seq.iter();
        let mut args = Vec::new();

        for arg in iterator {
            match arg {
                Value::Number(n) => {
                    let n = Felt252::from(n.as_u64().ok_or(VecArgError::NumberOutOfRange)?);
                    args.push(Arg::Value(n));
                }
                Value::String(n) => {
                    let n = Felt252::from(num_bigint::BigUint::from_str(n)?);
                    args.push(Arg::Value(n));
                }
                Value::Array(a) => {
                    let mut inner_args = Vec::new();
                    for x in a {
                        match x {
                            Value::Number(n) => {
                                let n =
                                    Felt252::from(n.as_u64().ok_or(VecArgError::NumberOutOfRange)?);
                                inner_args.push(Felt252::new(n));
                            }
                            Value::String(n) => {
                                let n = Felt252::from(num_bigint::BigUint::from_str(n)?);
                                inner_args.push(Felt252::new(n));
                            }
                            _ => return Err(VecArgError::ArrayParseError),
                        }
                    }
                    args.push(Arg::Array(inner_args));
                }
                _ => (),
            }
        }

        Ok(Self::new(args))
    }
}

impl<'de> Visitor<'de> for VecArg {
    type Value = VecArg;
    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
        formatter.write_str("a list of arguments")
    }
    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
    where
        A: serde::de::SeqAccess<'de>,
    {
        let mut args = Vec::new();
        while let Some(arg) = seq.next_element()? {
            match arg {
                Value::Number(n) => args.push(Value::Number(n)),
                Value::String(n) => args.push(Value::String(n)),
                Value::Array(a) => args.push(Value::Array(a)),
                _ => return Err(serde::de::Error::custom("Invalid type")),
            }
        }

        Self::visit_seq_helper(&args).map_err(|e| serde::de::Error::custom(e.to_string()))
    }
}

impl<'de> Deserialize<'de> for VecArg {
    fn deserialize<D>(deserializer: D) -> Result<VecArg, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_seq(VecArg(Vec::new()))
    }
}