vertigo/driver_module/js_value/
js_value_list_decoder.rs

1use std::collections::VecDeque;
2
3use super::js_json_struct::JsJson;
4use super::js_value_struct::JsValue;
5
6pub struct JsValueListDecoder {
7    data: VecDeque<JsValue>,
8}
9
10impl JsValueListDecoder {
11    pub fn new(data: Vec<JsValue>) -> JsValueListDecoder {
12        JsValueListDecoder {
13            data: VecDeque::from(data),
14        }
15    }
16
17    pub fn get_buffer(&mut self, label: &'static str) -> Result<Vec<u8>, String> {
18        let Some(value) = self.data.pop_front() else {
19            return Err(format!("{label} -> has no more params"));
20        };
21
22        match value {
23            JsValue::Vec(buffer) => Ok(buffer),
24            item => {
25                let name = item.typename();
26                Err(format!("{label} -> buffer expected, received {name}"))
27            }
28        }
29    }
30
31    pub fn get_u64(&mut self, label: &'static str) -> Result<u64, String> {
32        let Some(value) = self.data.pop_front() else {
33            return Err(format!("{label} -> has no more params"));
34        };
35
36        match value {
37            JsValue::U64(value) => Ok(value),
38            item => {
39                let name = item.typename();
40                Err(format!("{label} -> u64 expected, received {name}"))
41            }
42        }
43    }
44
45    pub fn get_u64_or_null(&mut self, label: &'static str) -> Result<Option<u64>, String> {
46        let Some(value) = self.data.pop_front() else {
47            return Err(format!("{label} -> has no more params"));
48        };
49
50        match value {
51            JsValue::U64(value) => Ok(Some(value)),
52            JsValue::Null => Ok(None),
53            item => {
54                let name = item.typename();
55                Err(format!("{label} -> Option<u64> expected, received {name}"))
56            }
57        }
58    }
59
60    pub fn get_string(&mut self, label: &'static str) -> Result<String, String> {
61        let Some(value) = self.data.pop_front() else {
62            return Err(format!("{label} -> has no more params"));
63        };
64
65        match value {
66            JsValue::String(value) => Ok(value),
67            item => {
68                let name = item.typename();
69                Err(format!("{label} -> String expected, received {name}"))
70            }
71        }
72    }
73
74    pub fn get_u32(&mut self, label: &'static str) -> Result<u32, String> {
75        let Some(value) = self.data.pop_front() else {
76            return Err(format!("{label} -> has no more params"));
77        };
78
79        match value {
80            JsValue::U32(value) => Ok(value),
81            item => {
82                let name = item.typename();
83                Err(format!("{label} -> u32 expected, received {name}"))
84            }
85        }
86    }
87
88    pub fn get_any(&mut self, label: &'static str) -> Result<JsValue, String> {
89        let Some(value) = self.data.pop_front() else {
90            return Err(format!("{label} -> has no more params"));
91        };
92
93        Ok(value)
94    }
95
96    pub fn get_json(&mut self, label: &'static str) -> Result<JsJson, String> {
97        let Some(value) = self.data.pop_front() else {
98            return Err(format!("{label} -> has no more params"));
99        };
100
101        match value {
102            JsValue::Json(value) => Ok(value),
103            item => {
104                let name = item.typename();
105                Err(format!("{label} -> json expected, received {name}"))
106            }
107        }
108    }
109
110    pub fn get_bool(&mut self, label: &'static str) -> Result<bool, String> {
111        let Some(value) = self.data.pop_front() else {
112            return Err(format!("{label} -> has no more params"));
113        };
114
115        match value {
116            JsValue::True => Ok(true),
117            JsValue::False => Ok(false),
118            item => {
119                let name = item.typename();
120                Err(format!("{label} -> bool expected, received {name}"))
121            }
122        }
123    }
124
125    pub fn get_vec<R, F: Fn(JsValue) -> Result<R, String>>(
126        &mut self,
127        label: &'static str,
128        convert: F,
129    ) -> Result<Vec<R>, String> {
130        let Some(value) = self.data.pop_front() else {
131            return Err(format!("{label} -> has no more params"));
132        };
133
134        let inner_list = match value {
135            JsValue::List(list) => list,
136            item => {
137                let name = item.typename();
138                return Err(format!("{label} -> list expected, received {name}"));
139            }
140        };
141
142        let mut result = Vec::new();
143
144        for (index, item) in inner_list.into_iter().enumerate() {
145            match convert(item) {
146                Ok(value) => {
147                    result.push(value);
148                }
149                Err(error) => {
150                    return Err(format!("{label} -> index:{index} -> {error}"));
151                }
152            }
153        }
154
155        Ok(result)
156    }
157
158    pub fn expect_no_more(self) -> Result<(), String> {
159        if self.data.is_empty() {
160            Ok(())
161        } else {
162            Err(String::from("Too many params"))
163        }
164    }
165}