#[macro_export]
macro_rules! json {
(null) => {
$crate::value::Value::Null
};
(true) => {
$crate::value::Value::from(true)
};
(false) => {
$crate::value::Value::from(false)
};
({}) => {{
use std::collections::HashMap;
use $crate::traits::ToValueBehavior;
HashMap::<String, $crate::value::Value>::new().to_value()
}};
({ $($key:tt : $value:tt),* $(,)? }) => {{
use std::collections::HashMap;
use $crate::traits::ToValueBehavior;
let mut map = HashMap::new();
$(
map.insert($key.to_string(), json!($value));
)*
map.to_value()
}};
({ $($key:tt : $value:expr),* $(,)? }) => {{
use std::collections::HashMap;
use $crate::traits::ToValueBehavior;
let mut map = HashMap::new();
$(
map.insert($key.to_string(), json!($value));
)*
map.to_value()
}};
([]) => {{
use $crate::traits::ToValueBehavior;
Vec::<$crate::value::Value>::new().to_value()
}};
([ $($value:tt),* $(,)? ]) => {{
use $crate::traits::ToValueBehavior;
vec![ $(json!($value)),* ].to_value()
}};
([ $($value:expr),* $(,)? ]) => {{
use $crate::traits::ToValueBehavior;
vec![ $(json!($value)),* ].to_value()
}};
($val:expr) => {{
use $crate::traits::ToValueBehavior;
($val).to_value()
}};
}
#[cfg(test)]
mod test {
use crate::{prelude::JsonMode, traits::ToValueBehavior};
use std::collections::HashMap;
#[test]
fn test_json_null() {
let null = json!(null);
assert_eq!(null, crate::value::Value::Null);
}
#[test]
fn test_json_booleans() {
let bool_true = json!(true);
assert_eq!(bool_true, crate::value::Value::from(true));
let bool_false = json!(false);
assert_eq!(bool_false, crate::value::Value::from(false));
}
#[test]
fn test_json_number() {
let number = json!(42);
assert_eq!(number, 42.to_value());
}
#[test]
fn test_json_string() {
let string = json!("hello");
assert_eq!(string, "hello".to_value());
}
#[test]
fn test_json_array() {
let array = json!(vec![1, 2, 3]);
assert_eq!(array, vec![1, 2, 3].to_value());
}
#[test]
fn test_json_variable() {
let test_val = true;
let from_var = json!(test_val);
assert_eq!(from_var, test_val.to_value());
}
#[test]
fn test_json_complex_structure() {
let mut map = HashMap::new();
map.insert("test".to_string(), true.to_value());
map.insert("test2".to_string(), "ok".to_value());
map.insert("test3".to_string(), vec![0, 1].to_value());
let complex = json!(map);
assert_eq!(complex, map.to_value());
}
#[test]
fn test_json_declarative() {
let data = json!({
"name": "test",
"value": 42,
"active": true
});
let expected = {
let mut map = HashMap::new();
map.insert("name".to_string(), "test".to_value());
map.insert("value".to_string(), 42.to_value());
map.insert("active".to_string(), true.to_value());
map.to_value()
};
assert_eq!(data, expected);
}
#[test]
fn test_json_declarative_with_expressions() {
let active = true;
let value = "42";
let data = json!({
"name": "test",
"value": value.parse::<i32>().unwrap(),
"active": active
});
let expected = {
let mut map = HashMap::new();
map.insert("name".to_string(), "test".to_value());
map.insert("value".to_string(), 42.to_value());
map.insert("active".to_string(), true.to_value());
map.to_value()
};
assert_eq!(data, expected);
}
#[test]
fn test_json_array_declarative() {
let value = "42";
let data = json!([1, "hello", true, value.parse::<i32>().unwrap()]);
let expected = vec![
1.to_value(),
"hello".to_value(),
true.to_value(),
42.to_value(),
]
.to_value();
assert_eq!(data, expected);
}
#[test]
fn test_json_empty_containers() {
let empty_obj = json!({});
let empty_arr = json!([]);
assert_eq!(
empty_obj,
HashMap::<String, crate::value::Value>::new().to_value()
);
assert_eq!(empty_arr, Vec::<crate::value::Value>::new().to_value());
}
#[test]
fn test_json_nested_structures() {
let data = json!({
"user": {
"id": 1,
"name": "Alice",
"roles": ["admin", "user"]
},
"active": true,
"score": 99.5
});
let mut user_map = HashMap::new();
user_map.insert("id".to_string(), 1.to_value());
user_map.insert("name".to_string(), "Alice".to_value());
user_map.insert(
"roles".to_string(),
vec!["admin".to_value(), "user".to_value()].to_value(),
);
let mut expected_map = HashMap::new();
expected_map.insert("user".to_string(), user_map.to_value());
expected_map.insert("active".to_string(), true.to_value());
expected_map.insert("score".to_string(), 99.5.to_value());
assert_eq!(data, expected_map.to_value());
}
#[test]
fn test_recursive_json() {
let inner = json!({
"level2": r#"<img src="level2.png" />"#
});
let data = json!({
"level1": inner
});
let mut level2_map = HashMap::new();
level2_map.insert(
"level2".to_string(),
r#"<img src="level2.png" />"#.to_value(),
);
let mut expected_map = HashMap::new();
expected_map.insert("level1".to_string(), level2_map.to_value());
assert_eq!(data, expected_map.to_value());
let string_json = data.to_json(JsonMode::Inline);
let expected_json = r#"{"level1":{"level2":"<img src=\"level2.png\" />"}}"#;
assert_eq!(string_json, expected_json);
}
}