#![cfg(feature="std")]
use {
core::convert::TryFrom,
std::io::Write,
sj::{IoResult, Value}
};
#[derive(Debug)]
enum JsonFile {
Array,
UglyArray,
NiceArray,
Object,
UglyObject,
NiceObject,
Ugly,
Nice,
}
impl JsonFile {
fn load<'a>(&self) -> &'a str {
let (result, should_trim) = match self {
JsonFile::Array => (include_str!("array.json"), true),
JsonFile::UglyArray => (include_str!("ugly-array.json"), false),
JsonFile::NiceArray => (include_str!("nice-array.json"), true),
JsonFile::Object => (include_str!("object.json"), true),
JsonFile::UglyObject => (include_str!("ugly-object.json"), false),
JsonFile::NiceObject => (include_str!("nice-object.json"), true),
JsonFile::Ugly => (include_str!("ugly.json"), false),
JsonFile::Nice => (include_str!("nice.json"), true),
};
let result = &result[result.find('\n').unwrap()..];
match should_trim {
true => result.trim(),
false => result,
}
}
}
#[test]
fn arrays() -> IoResult<()> {
match sj::parse_bytes("[]")? {
Value::Array(array) => assert!(array.is_empty()),
other => panic!("Expected array, got: {:?}", other),
};
let value = sj::parse_bytes(JsonFile::UglyArray.load())?;
match value {
Value::Array(ref array) => match (array.first(), array.last(), array.len()) {
(Some(Value::String(s)), Some(Value::Array(sub_array)), 2) if s == "some" => match (
sub_array.first(), sub_array.last(), sub_array.len(),
) {
(Some(Value::Array(last_array)), Some(Value::Object(object)), 2) if last_array.is_empty() && object.is_empty()
=> for (json, expected) in &[
(value.format()?, JsonFile::Array.load()),
(value.format_nicely(Some(2))?, JsonFile::NiceArray.load()),
] {
assert_eq!(json, expected);
},
other => panic!("Expected last array to be empty, got: {:?}", other),
},
other => panic!("Expected array with one string and one sub array, got: {:?}", other),
},
other => panic!("Expected array, got: {:?}", other),
};
Ok(())
}
#[test]
fn objects() -> IoResult<()> {
match sj::parse_bytes("{}")? {
Value::Object(object) => assert!(object.is_empty()),
other => panic!("Expected object, got: {:?}", other),
};
let value = sj::parse_bytes(JsonFile::UglyObject.load())?;
match value {
Value::Object(ref object) => match (object.get("some"), object.get("u8"), object.len()) {
(Some(Value::Array(array)), Some(Value::Number(n)), 2) => match (u8::try_from(n), array.first(), array.len()) {
(Ok(99), Some(Value::String(s)), 1) if s == "thing" => for (json, expected) in &[
(value.format()?, JsonFile::Object.load()),
(value.format_nicely(None)?, JsonFile::NiceObject.load()),
] {
assert_eq!(json, expected);
},
_ => panic!("Expected array with one string, got: {:?}", array),
},
_ => panic!("Expected object with two pairs, got: {:?}", object),
},
other => panic!("Expected object, got: {:?}", other),
};
Ok(())
}
#[test]
fn numbers() -> IoResult<()> {
let value = sj::parse_bytes("[10, -0, -1.0, 10.5E+5, -99e-6, -6e7, null, true, false]")?;
match value {
Value::Array(ref a) if a.len() == 9 => match (
a.get(0), a.get(1), a.get(2), a.get(3), a.get(4), a.get(5), a.get(6), a.get(7), a.get(8),
) {
(
Some(Value::Number(n0)), Some(Value::Number(n1)), Some(Value::Number(n2)), Some(Value::Number(n3)), Some(Value::Number(n4)),
Some(Value::Number(n5)), Some(Value::Null), Some(Value::Boolean(true)), Some(Value::Boolean(false)),
) => match (u8::try_from(n0), i8::try_from(n1), f64::try_from(n2), f64::try_from(n3), f64::try_from(n4), f64::try_from(n5)) {
(Ok(10), Ok(0), Ok(n2), Ok(n3), Ok(n4), Ok(n5)) if n2 == -1.0 && n3 == 10.5e5 && n4 == -99e-6 && n5 == -6e7 => {
std::println!("{}", value.format_nicely(None)?);
},
other => panic!("Expected 5 primitive numbers, 1 error, 1 null and 2 booleans, got: {:?}", other),
},
_ => panic!("Expected 9 items, got: {:?}", a),
},
_ => panic!("Expected array of 9 items, got: {:?}", value),
};
Ok(())
}
#[test]
fn formats() -> IoResult<()> {
let value = sj::parse_bytes(JsonFile::Ugly.load())?;
let formatted = value.format_nicely_as_bytes(None)?;
let expected = JsonFile::Nice.load().as_bytes();
assert_eq!(formatted, expected);
let mut buf = Vec::with_capacity(formatted.len());
value.write_nicely(None, &mut buf)?;
buf.flush()?;
assert_eq!(buf, expected);
Ok(())
}