use std::borrow::{Borrow, BorrowMut};
use std::convert::TryFrom;
use ijson::{ijson, IArray, INumber, IObject, IString, IValue};
macro_rules! check_conversions {
($subtype:expr, $t:ty, $wrong:expr) => {{
let mut subtype: $t = $subtype;
let _: &IValue = subtype.as_ref();
let _: &IValue = subtype.borrow();
let _: &mut IValue = subtype.as_mut();
let _: &mut IValue = subtype.borrow_mut();
let value = IValue::from(subtype.clone());
assert_eq!(<$t>::try_from(value.clone()).unwrap(), subtype);
assert_eq!(*<&$t>::try_from(&value).unwrap(), subtype);
let mut value_mut = value.clone();
assert_eq!(*<&mut $t>::try_from(&mut value_mut).unwrap(), subtype);
let mut wrong = $wrong;
assert!(<$t>::try_from(wrong.clone()).is_err());
assert!(<&$t>::try_from(&wrong).is_err());
assert!(<&mut $t>::try_from(&mut wrong).is_err());
}};
}
#[test]
fn subtype_value_conversions() {
let mut obj = IObject::new();
obj.insert("k", IValue::from(1));
check_conversions!(obj, IObject, IValue::NULL);
let mut arr = IArray::new();
arr.push(IValue::from(1));
check_conversions!(arr, IArray, IValue::NULL);
check_conversions!(IString::intern("hello"), IString, IValue::NULL);
check_conversions!(INumber::from(42), INumber, IValue::from("not a number"));
}
#[test]
fn ijson_macro_builds_every_shape() {
let v = ijson!({
"null": null,
"yes": true,
"no": false,
"nested": [1, 2, [3, 4], { "deep": 5 }],
"text": "s",
"empty_arr": [],
"empty_obj": {}
});
let o = v.as_object().expect("top level is an object");
assert!(o["null"].is_null());
assert!(o["yes"].is_true());
assert!(o["no"].is_false());
assert_eq!(o["text"].as_string().unwrap().as_str(), "s");
assert_eq!(o["empty_arr"].as_array().unwrap().len(), 0);
assert_eq!(o["empty_obj"].as_object().unwrap().len(), 0);
let nested = o["nested"].as_array().expect("nested is an array");
assert_eq!(nested.len(), 4);
assert_eq!(nested[0], IValue::from(1));
assert_eq!(nested[2].as_array().unwrap().len(), 2);
assert_eq!(nested[3].as_object().unwrap()["deep"], IValue::from(5));
let count = 7;
let with_var = ijson!({ "n": count });
assert_eq!(with_var.as_object().unwrap()["n"], IValue::from(7));
let arr = ijson!([true, null, "x"]);
assert_eq!(arr.as_array().unwrap().len(), 3);
assert_eq!(ijson!(42), IValue::from(42));
}