cairo_args_runner/utils/
args.rs

1use std::{ops::Deref, str::FromStr};
2
3use cairo_felt::Felt252;
4use cairo_lang_runner::Arg;
5use serde::{de::Visitor, Deserialize};
6use serde_json::Value;
7use thiserror::Error;
8
9#[derive(Error, Debug)]
10pub enum VecArgError {
11    #[error("failed to parse array")]
12    ArrayParseError,
13    #[error("failed to parse number: {0}")]
14    NumberParseError(#[from] std::num::ParseIntError),
15    #[error("failed to parse bigint: {0}")]
16    BigIntParseError(#[from] num_bigint::ParseBigIntError),
17    #[error("number out of range")]
18    NumberOutOfRange,
19}
20
21/// `VecArg` is a wrapper around a vector of `Arg`.
22///
23/// It provides convenience methods for working with a vector of `Arg` and implements
24/// `Deref` to allow it to be treated like a vector of `Arg`.
25#[derive(Debug)]
26pub struct VecArg(Vec<Arg>);
27
28impl VecArg {
29    /// Creates a new `VecArg` from a vector of `Arg`.
30    ///
31    /// # Arguments
32    ///
33    /// * `VecArg` - A vector of `Arg`.
34    ///
35    /// # Returns
36    ///
37    /// * `VecArg` - A new `VecArg` instance.
38    #[must_use]
39    pub fn new(args: Vec<Arg>) -> Self {
40        Self(args)
41    }
42}
43
44impl Deref for VecArg {
45    type Target = Vec<Arg>;
46    fn deref(&self) -> &Self::Target {
47        &self.0
48    }
49}
50
51impl From<VecArg> for Vec<Arg> {
52    fn from(args: VecArg) -> Self {
53        args.0
54    }
55}
56
57impl From<Vec<Arg>> for VecArg {
58    fn from(args: Vec<Arg>) -> Self {
59        Self(args)
60    }
61}
62
63impl VecArg {
64    fn visit_seq_helper(seq: &[Value]) -> Result<Self, VecArgError> {
65        let iterator = seq.iter();
66        let mut args = Vec::new();
67
68        for arg in iterator {
69            match arg {
70                Value::Number(n) => {
71                    let n = Felt252::from(n.as_u64().ok_or(VecArgError::NumberOutOfRange)?);
72                    args.push(Arg::Value(n));
73                }
74                Value::String(n) => {
75                    let n = Felt252::from(num_bigint::BigUint::from_str(n)?);
76                    args.push(Arg::Value(n));
77                }
78                Value::Array(a) => {
79                    let mut inner_args = Vec::new();
80                    for x in a {
81                        match x {
82                            Value::Number(n) => {
83                                let n =
84                                    Felt252::from(n.as_u64().ok_or(VecArgError::NumberOutOfRange)?);
85                                inner_args.push(Felt252::new(n));
86                            }
87                            Value::String(n) => {
88                                let n = Felt252::from(num_bigint::BigUint::from_str(n)?);
89                                inner_args.push(Felt252::new(n));
90                            }
91                            _ => return Err(VecArgError::ArrayParseError),
92                        }
93                    }
94                    args.push(Arg::Array(inner_args));
95                }
96                _ => (),
97            }
98        }
99
100        Ok(Self::new(args))
101    }
102}
103
104impl<'de> Visitor<'de> for VecArg {
105    type Value = VecArg;
106    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
107        formatter.write_str("a list of arguments")
108    }
109    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
110    where
111        A: serde::de::SeqAccess<'de>,
112    {
113        let mut args = Vec::new();
114        while let Some(arg) = seq.next_element()? {
115            match arg {
116                Value::Number(n) => args.push(Value::Number(n)),
117                Value::String(n) => args.push(Value::String(n)),
118                Value::Array(a) => args.push(Value::Array(a)),
119                _ => return Err(serde::de::Error::custom("Invalid type")),
120            }
121        }
122
123        Self::visit_seq_helper(&args).map_err(|e| serde::de::Error::custom(e.to_string()))
124    }
125}
126
127impl<'de> Deserialize<'de> for VecArg {
128    fn deserialize<D>(deserializer: D) -> Result<VecArg, D::Error>
129    where
130        D: serde::Deserializer<'de>,
131    {
132        deserializer.deserialize_seq(VecArg(Vec::new()))
133    }
134}