1#[macro_export]
17macro_rules! fact {
18 ($predicate:expr, $($args:tt)*) => {{
19 let mut args = vec![];
20 $crate::push_values!(args; $($args)+);
21 $crate::Fact {
22 predicate: $predicate.to_owned(),
23 args,
24 }
25 }};
26}
27
28#[macro_export]
29macro_rules! value {
30 ($lit:literal) => {
31 $crate::Value::from($lit)
32 };
33 ($type_:ident { $id:expr }) => {
34 $crate::Value::new(stringify!($type_), $id)
35 };
36 ($val:expr) => {
37 $crate::Value::from($val)
38 };
39}
40
41#[macro_export]
42macro_rules! push_values {
43 ($args:expr; $str:literal) => {{
44 $args.push($crate::value!($str));
45 }};
46 ($args:expr; $type_:ident { $id:expr }) => {{
47 $args.push($crate::value!($type_ { $id }));
48 }};
49
50 ($args:expr; $str:literal, $($rest:tt)*) => {{
51 $args.push($crate::value!($str));
52 $crate::push_values!($args; $($rest)*);
53 }};
54 ($args:expr; $type_:ident { $id:expr }, $($rest:tt)*) => {{
55 $args.push($crate::value!($type_ { $id }));
56 $crate::push_values!($args; $($rest)*);
57 }};
58 ($args:expr; $val:expr) => {{
59 $args.push($crate::value!($val));
60 }};
61 ($args:expr; $val:expr, $($rest:tt)*) => {{
62 $args.push($crate::value!($val));
63 $crate::push_values!($args; $($rest)*);
64 }};
65}
66
67#[cfg(test)]
68mod test {
69 use crate::{
70 polar_ast::{PRIMITIVE_BOOLEAN_SYMBOL, PRIMITIVE_INTEGER_SYMBOL, PRIMITIVE_STRING_SYMBOL},
71 Fact, Value,
72 };
73
74 #[test]
75 fn test_macro_expansion() {
76 let bool_val = value!(true);
77 assert_eq!(bool_val, Value::new(PRIMITIVE_BOOLEAN_SYMBOL, "true"));
78
79 let string_val = value!("foo");
80 assert_eq!(string_val, Value::new(PRIMITIVE_STRING_SYMBOL, "foo"));
81
82 let int_val = value!(42);
83 assert_eq!(int_val, Value::new(PRIMITIVE_INTEGER_SYMBOL, "42"));
84
85 let literal_val = value!(Foo { "bar" });
86 assert_eq!(literal_val, Value::new("Foo", "bar"));
87
88 let fact = fact!("foo", "bar", 42, true, Foo { "bar" });
89 assert_eq!(
90 fact,
91 Fact {
92 predicate: "foo".to_string(),
93 args: vec![
94 Value::new(PRIMITIVE_STRING_SYMBOL, "bar"),
95 Value::new(PRIMITIVE_INTEGER_SYMBOL, "42"),
96 Value::new(PRIMITIVE_BOOLEAN_SYMBOL, "true"),
97 Value::new("Foo", "bar"),
98 ],
99 }
100 );
101 }
102}