zen_expression/functions/
arguments.rs

1use crate::variable::RcCell;
2use crate::Variable;
3use ahash::HashMap;
4use anyhow::Context;
5use rust_decimal::Decimal;
6use std::ops::Deref;
7
8pub struct Arguments<'a>(pub &'a [Variable]);
9
10impl<'a> Deref for Arguments<'a> {
11    type Target = [Variable];
12
13    fn deref(&self) -> &'a Self::Target {
14        &self.0
15    }
16}
17
18impl<'a> Arguments<'a> {
19    pub fn ovar(&self, pos: usize) -> Option<&'a Variable> {
20        self.0.get(pos)
21    }
22
23    pub fn var(&self, pos: usize) -> anyhow::Result<&'a Variable> {
24        self.ovar(pos)
25            .with_context(|| format!("Argument on {pos} position out of bounds"))
26    }
27
28    pub fn obool(&self, pos: usize) -> anyhow::Result<Option<bool>> {
29        match self.ovar(pos) {
30            Some(v) => v
31                .as_bool()
32                .map(Some)
33                .with_context(|| format!("Argument on {pos} is not a bool")),
34            None => Ok(None),
35        }
36    }
37
38    pub fn bool(&self, pos: usize) -> anyhow::Result<bool> {
39        self.obool(pos)?
40            .with_context(|| format!("Argument on {pos} position is not a valid bool"))
41    }
42
43    pub fn ostr(&self, pos: usize) -> anyhow::Result<Option<&'a str>> {
44        match self.ovar(pos) {
45            Some(v) => v
46                .as_str()
47                .map(Some)
48                .with_context(|| format!("Argument on {pos} is not a string")),
49            None => Ok(None),
50        }
51    }
52
53    pub fn str(&self, pos: usize) -> anyhow::Result<&'a str> {
54        self.ostr(pos)?
55            .with_context(|| format!("Argument on {pos} position is not a valid string"))
56    }
57
58    pub fn onumber(&self, pos: usize) -> anyhow::Result<Option<Decimal>> {
59        match self.ovar(pos) {
60            Some(v) => v
61                .as_number()
62                .map(Some)
63                .with_context(|| format!("Argument on {pos} is not a number")),
64            None => Ok(None),
65        }
66    }
67
68    pub fn number(&self, pos: usize) -> anyhow::Result<Decimal> {
69        self.onumber(pos)?
70            .with_context(|| format!("Argument on {pos} position is not a valid number"))
71    }
72
73    pub fn oarray(&self, pos: usize) -> anyhow::Result<Option<RcCell<Vec<Variable>>>> {
74        match self.ovar(pos) {
75            Some(v) => v
76                .as_array()
77                .map(Some)
78                .with_context(|| format!("Argument on {pos} is not a array")),
79            None => Ok(None),
80        }
81    }
82
83    pub fn array(&self, pos: usize) -> anyhow::Result<RcCell<Vec<Variable>>> {
84        self.oarray(pos)?
85            .with_context(|| format!("Argument on {pos} position is not a valid array"))
86    }
87
88    pub fn oobject(&self, pos: usize) -> anyhow::Result<Option<RcCell<HashMap<String, Variable>>>> {
89        match self.ovar(pos) {
90            Some(v) => v
91                .as_object()
92                .map(Some)
93                .with_context(|| format!("Argument on {pos} is not a object")),
94            None => Ok(None),
95        }
96    }
97
98    pub fn object(&self, pos: usize) -> anyhow::Result<RcCell<HashMap<String, Variable>>> {
99        self.oobject(pos)?
100            .with_context(|| format!("Argument on {pos} position is not a valid object"))
101    }
102}