use std::fs;
use std::path::Path;
use std::fmt::Display;
use std::error::Error;
use crate::value::Value;
use crate::parser::Parser;
pub mod value;
pub mod parser;
pub fn load_from_file<P: AsRef<Path> + Display>(path: P) -> Result<Value, Box<dyn Error>> {
Ok(Parser::new(fs::File::open(path)?).parse()?)
}
#[cfg(test)]
mod tests {
use crate::value;
#[test]
fn test_empty_object_and_array() {
let empty_obj: value::Value = b"{}".as_slice().into();
assert!(empty_obj .is_object());
assert!(!empty_obj.as_bool());
let empty_array: value::Value = "[]".as_bytes().into();
assert!(empty_array.is_array());
assert!(!empty_array.as_bool());
}
#[test]
fn test_weird_numbers() {
let mut v :value::Value = "0.0".as_bytes().into();
assert_eq!(v.as_i64(), 0);
v = "0E0".as_bytes().into();
assert_eq!(v.as_i64(), 0);
v = "0e-0".as_bytes().into();
assert_eq!(v.as_i64(), 0);
}
#[test]
fn test_string() {
let mut v :value::Value = "\"abc\"".as_bytes().into();
assert_eq!(v.as_str(), "abc");
v = "'ABC'".as_bytes().into();
assert_eq!(v.as_str(), "ABC");
v = "'\\r\\n\\t'".as_bytes().into();
assert_eq!(v.as_str(), "\r\n\t");
}
#[test]
fn all() {
let s = r##"
# this is a json conf file
#
{
"null_key": null,
"i64_key": 1,
"i64_sci_key": 123E+4,
"i64_0x_key": 0xAf,
"f64_key": 3.14,
"f64_sci_key": 3.14e-2,
"true_key": true,
"false_key": false, # comment in line
'single_quote_key': 'a single quote value',
"object_key": {
"inner_key1": "abc",
"inner_key2": 3.14E3,
},
"array_key": [1, "abc", ],
}
"##;
let v = s.parse::<value::Value>().unwrap();
assert!(v.is_object());
assert!(!v.is_null());
assert!(v.has("i64_key"));
assert!(!v["null_key"].as_bool());
assert!(v["i64_key"].as_bool());
assert_eq!(v["i64_key"].as_i64(), 1);
assert_eq!(v["f64_key"].as_f64(), 3.14);
assert_eq!(v["object_key"]["inner_key1"].as_str(), "abc");
assert_eq!(v["array_key"][1].as_str(), "abc");
v["array_key"].iter_array().for_each(|v| {println!("{:?}", v); });
v.iter_object().for_each(|(k, v)| { println!("{}: {:?}", k, v); });
}
}