#[macro_export]
macro_rules! record {
{$($col:expr => $val:expr),* $(,)?} => {
$crate::Record::from_iter(::std::vec![ $(
(::std::string::String::from($col), $val)
),* ])
};
}
#[macro_export]
macro_rules! test_record {
{$($col:expr => $val:expr),* $(,)?} => {
$crate::Value::test_record($crate::record! { $(
$col => $crate::IntoValue::into_value($val, $crate::Span::test_data())
),* })
};
}
#[doc(hidden)]
pub const fn count_helper<const N: usize>(_: [(); N]) -> usize {
N
}
#[macro_export]
macro_rules! test_table {
(@replace_expr $_t:tt $sub:expr) => { $sub };
(@count_tts $($smth:tt)*) => {
$crate::macros::count_helper([$($crate::test_table!(@replace_expr $smth ())),*])
};
[[$($col:expr),+ $(,)?]; $([$($val:expr),+ $(,)?]),+ $(,)?] => {{
const COLUMNS: usize = $crate::test_table!(@count_tts $($col)+);
let columns: ::std::vec::Vec<::std::string::String> = ::std::vec![$($col.into()),+];
let rows = vec![ $(
{
const ROW_ITEMS: usize = $crate::test_table!(@count_tts $($val)+);
const _: () = assert!(ROW_ITEMS == COLUMNS) ;
$crate::Value::test_record($crate::Record::from_raw_cols_vals(
columns.clone(),
::std::vec![ $(
$crate::IntoValue::into_value($val, $crate::Span::test_data())
),+ ],
$crate::Span::test_data(),
$crate::Span::test_data(),
).expect("Number of columns and rows should be equal"))
}
),+ ];
$crate::Value::test_list(rows)
}};
}
#[macro_export]
macro_rules! test_list {
[$($entry:expr),* $(,)?] => {
$crate::Value::test_list(::std::vec![
$($crate::IntoValue::into_value($entry, $crate::Span::test_data())),*
])
};
}
#[macro_export]
macro_rules! test_value {
(@recur, [$($item:tt),* $(,)?]) => {
$crate::test_list![$(
$crate::test_value!(@recur, $item)
),*]
};
(@recur, {$($col:tt : $val:tt),* $(,)?}) => {
$crate::test_record! { $(
$crate::test_value!(@col, $col) => $crate::test_value!(@recur, $val)
),* }
};
(@recur, $val:expr) => { $val };
(@col, $col:ident) => { stringify!($col) };
(@col, $col:expr) => { $col };
([$($item:tt),* $(,)?]) => { $crate::test_value!(@recur, [$($item),*]) };
({$($col:tt : $val:tt),* $(,)?}) => { $crate::test_value!(@recur, {$($col : $val),*}) };
($val:expr) => { $crate::IntoValue::into_value($val, $crate::Span::test_data()) };
}
#[cfg(test)]
mod test_value_macro_tests {
use pretty_assertions::assert_eq;
use crate::{IntoValue, Span};
#[test]
fn ident_record_columns() {
let foo_col = "foo_val";
let x = test_value!({
a: 2,
b: 3,
foo_col: foo_col,
(foo_col): foo_col,
});
let expected = test_record! {
"a" => 2,
"b" => 3,
"foo_col" => "foo_val",
"foo_val" => "foo_val",
};
assert_eq!(x, expected);
}
#[test]
fn simple_values() {
let x = test_value!(10);
let expected = 10.into_value(Span::test_data());
assert_eq!(x, expected);
let x = test_value!(true);
let expected = true.into_value(Span::test_data());
assert_eq!(x, expected);
let x = test_value!(());
let expected = ().into_value(Span::test_data());
assert_eq!(x, expected);
}
#[test]
fn simple_record() {
let x = test_value!({
"a": 1,
"b": 2,
"c": 3,
});
let expected = test_record! {
"a" => 1,
"b" => 2,
"c" => 3,
};
assert_eq!(x, expected);
}
#[test]
fn simple_list() {
let x = test_value!(["abc", 42, true,]);
let expected = test_list!["abc", 42, true,];
assert_eq!(x, expected);
}
#[test]
fn nested_records() {
let x = test_value!({
"a": 1,
"b": 2,
"c": {
"d": 4,
"e": 5,
"f": {
"g": 7,
"h": 8,
}
},
});
let expected = test_record! {
"a" => 1,
"b" => 2,
"c" => test_record! {
"d" => 4,
"e" => 5,
"f" => test_record! {
"g" => 7,
"h" => 8,
}
},
};
assert_eq!(x, expected);
}
#[test]
fn nested_lists() {
let x = test_value!(["a", "b", ["c", "d", ["e", "f",],],]);
let expected = test_list!["a", "b", test_list!["c", "d", test_list!["e", "f",],],];
assert_eq!(x, expected);
}
#[test]
fn complex_value() {
let x = test_value!({
"a": 1,
"b": {
"b_a": 3,
"b_b": 4,
},
"c": [1, "two", ()],
"d": [
{"foo": 1, "bar": 10},
{"foo": 2, "bar": 20},
{"foo": 3, "bar": 30},
],
});
let expected = test_record! {
"a" => 1,
"b" => test_record! {
"b_a" => 3,
"b_b" => 4,
},
"c" => test_list![1, "two", ()],
"d" => test_list![
test_record! {"foo" => 1, "bar" => 10},
test_record! {"foo" => 2, "bar" => 20},
test_record! {"foo" => 3, "bar" => 30},
],
};
assert_eq!(x, expected)
}
#[test]
fn complex_value_with_ident_keys() {
let x = test_value!({
a: 1,
b: {
b_a: 3,
b_b: 4,
},
c: [1, "two", ()],
d: [
{foo: 1, bar: 10},
{foo: 2, bar: 20},
{foo: 3, bar: 30},
],
});
let expected = test_record! {
"a" => 1,
"b" => test_record! {
"b_a" => 3,
"b_b" => 4,
},
"c" => test_list![1, "two", ()],
"d" => test_list![
test_record! {"foo" => 1, "bar" => 10},
test_record! {"foo" => 2, "bar" => 20},
test_record! {"foo" => 3, "bar" => 30},
],
};
assert_eq!(x, expected)
}
}