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