#[macro_export]
macro_rules! int {
($int:expr) => {{
use num_bigint::BigInt;
let _b: BigInt = $int.into();
_b
}};
}
#[macro_export]
macro_rules! frac {
($int1:expr, $int2:expr) => {{
::num_rational::BigRational::new($int1.into(), $int2.into())
}};
}
#[macro_export]
macro_rules! arr {
[] => {
$crate::arr::Arr::from_vec(vec![]).unwrap()
};
[ $( $elem:expr ),+ , ] => {
try_arr![ $( $elem ),+ ].unwrap()
};
[ $( $elem:expr ),+ ] => {
try_arr![ $( $elem ),+ ].unwrap()
};
}
#[macro_export]
macro_rules! try_arr {
[ $( $elem:expr ),+ , ] => {
try_arr![ $( $elem ),+ ]
};
[ $( $elem:expr ),+ ] => {
{
$crate::arr::Arr::from_vec(vec![ $( $elem.into() ),+ ])
}
};
}
#[macro_export]
macro_rules! tup {
( $( $elem:expr ),* , ) => {
tup!( $( $elem ),* )
};
( $( $elem:expr ),* ) => {
{
$crate::tup::Tup::from_vec(vec![ $( $elem.into() ),+ ])
}
};
}
#[macro_export]
macro_rules! obj {
{} => {
$crate::obj::Obj::from_map_unchecked(::std::collections::HashMap::new())
};
{ $( $field:expr => $inner:expr ),+ , } => {
try_obj!{ $( $field => $inner ),+ }.unwrap()
};
{ $( $field:expr => $inner:expr ),+ } => {
try_obj!{ $( $field => $inner ),+ }.unwrap()
};
}
#[macro_export]
macro_rules! try_obj {
{ $( $field:expr => $inner:expr ),+ , } => {
try_obj!{ $( $field => $inner ),* };
};
{ $( $field:expr => $inner:expr ),+ } => {
#[allow(clippy::useless_let_if_seq)]
{
use $crate::obj::Obj;
let mut _map = ::std::collections::HashMap::new();
let mut _parent: Option<$crate::value::Value> = None;
$(
if $field == "^" {
_parent = Some($inner.into());
} else {
_map.insert($field.into(), $inner.into());
}
)*
match _parent {
Some(parent) => match parent.get_obj() {
Ok(parent) => Obj::from_map_with_parent(_map, parent),
e @ Err(_) => e,
}
None => Obj::from_map(_map),
}
}
};
}
#[cfg(test)]
mod tests {
use crate::obj::Obj;
use crate::types::Type::*;
use crate::value::Value;
use crate::OverError;
#[test]
fn arr_basic() {
assert_eq!(
arr![Value::Int(1.into()), Value::Int(2.into())],
try_arr![1, 2].unwrap()
);
assert_ne!(
arr![-1, 2],
try_arr![Value::Int(1.into()), Value::Int(2.into())].unwrap()
);
}
#[test]
fn try_arr_mismatch() {
assert_eq!(
try_arr![arr![1, 1], arr!['c']],
Err(OverError::ArrTypeMismatch(
Arr(Box::new(Int)),
Arr(Box::new(Char)),
))
);
assert_eq!(try_arr![1, 'c'], Err(OverError::ArrTypeMismatch(Int, Char)));
}
#[test]
fn obj_basic() {
let obj = Obj::from_map_unchecked(map! {"a".into() => 1.into(),
"b".into() => arr![1, 2].into()});
assert_eq!(
obj,
obj! {
"a" => 1,
"b" => arr![1, 2]
}
);
}
}