1#[macro_export]
5macro_rules! int {
6 ($int:expr) => {{
7 use num_bigint::BigInt;
8
9 let _b: BigInt = $int.into();
10 _b
11 }};
12}
13
14#[macro_export]
16macro_rules! frac {
17 ($int1:expr, $int2:expr) => {{
18 ::num_rational::BigRational::new($int1.into(), $int2.into())
19 }};
20}
21
22#[macro_export]
28macro_rules! arr {
29 [] => {
30 $crate::arr::Arr::from_vec(vec![]).unwrap()
31 };
32 [ $( $elem:expr ),+ , ] => {
33 try_arr![ $( $elem ),+ ].unwrap()
35 };
36 [ $( $elem:expr ),+ ] => {
37 try_arr![ $( $elem ),+ ].unwrap()
38 };
39}
40
41#[macro_export]
45macro_rules! try_arr {
46 [ $( $elem:expr ),+ , ] => {
47 try_arr![ $( $elem ),+ ]
49 };
50 [ $( $elem:expr ),+ ] => {
51 {
52 $crate::arr::Arr::from_vec(vec![ $( $elem.into() ),+ ])
53 }
54 };
55}
56
57#[macro_export]
60macro_rules! tup {
61 ( $( $elem:expr ),* , ) => {
62 tup!( $( $elem ),* )
63 };
64 ( $( $elem:expr ),* ) => {
65 {
66 $crate::tup::Tup::from_vec(vec![ $( $elem.into() ),+ ])
67 }
68 };
69}
70
71#[macro_export]
77macro_rules! obj {
78 {} => {
79 $crate::obj::Obj::from_map_unchecked(::std::collections::HashMap::new())
80 };
81 { $( $field:expr => $inner:expr ),+ , } => {
82 try_obj!{ $( $field => $inner ),+ }.unwrap()
84 };
85 { $( $field:expr => $inner:expr ),+ } => {
86 try_obj!{ $( $field => $inner ),+ }.unwrap()
87 };
88}
89
90#[macro_export]
94macro_rules! try_obj {
95 { $( $field:expr => $inner:expr ),+ , } => {
96 try_obj!{ $( $field => $inner ),* };
98 };
99 { $( $field:expr => $inner:expr ),+ } => {
100 #[allow(clippy::useless_let_if_seq)]
101 {
102 use $crate::obj::Obj;
103
104 let mut _map = ::std::collections::HashMap::new();
105 let mut _parent: Option<$crate::value::Value> = None;
106
107 $(
108 if $field == "^" {
109 _parent = Some($inner.into());
110 } else {
111 _map.insert($field.into(), $inner.into());
112 }
113 )*
114
115 match _parent {
116 Some(parent) => match parent.get_obj() {
117 Ok(parent) => Obj::from_map_with_parent(_map, parent),
118 e @ Err(_) => e,
119 }
120 None => Obj::from_map(_map),
121 }
122 }
123 };
124}
125
126#[cfg(test)]
127mod tests {
128 use crate::obj::Obj;
129 use crate::types::Type::*;
130 use crate::value::Value;
131 use crate::OverError;
132
133 #[test]
134 fn arr_basic() {
135 assert_eq!(
136 arr![Value::Int(1.into()), Value::Int(2.into())],
137 try_arr![1, 2].unwrap()
138 );
139
140 assert_ne!(
141 arr![-1, 2],
142 try_arr![Value::Int(1.into()), Value::Int(2.into())].unwrap()
143 );
144 }
145
146 #[test]
147 fn try_arr_mismatch() {
148 assert_eq!(
149 try_arr![arr![1, 1], arr!['c']],
150 Err(OverError::ArrTypeMismatch(
151 Arr(Box::new(Int)),
152 Arr(Box::new(Char)),
153 ))
154 );
155 assert_eq!(try_arr![1, 'c'], Err(OverError::ArrTypeMismatch(Int, Char)));
156 }
157
158 #[test]
159 fn obj_basic() {
160 let obj = Obj::from_map_unchecked(map! {"a".into() => 1.into(),
161 "b".into() => arr![1, 2].into()});
162
163 assert_eq!(
164 obj,
165 obj! {
166 "a" => 1,
167 "b" => arr![1, 2]
168 }
169 );
170 }
171}