use rustlavel_core::Json;
use std::cmp::Ordering;
pub fn truthy(value: &Json) -> bool {
match value {
Json::Null => false,
Json::Bool(flag) => *flag,
Json::Number(number) => *number != 0.0 && !number.is_nan(),
Json::String(text) => !text.is_empty(),
Json::Array(items) => !items.is_empty(),
Json::Object(map) => !map.is_empty(),
}
}
pub fn compare(left: &Json, right: &Json) -> Option<Ordering> {
match (left, right) {
(Json::Number(a), Json::Number(b)) => a.partial_cmp(b),
(Json::String(a), Json::String(b)) => Some(a.cmp(b)),
_ => None,
}
}
pub fn to_text(value: &Json) -> String {
match value {
Json::Null => String::new(),
Json::Bool(flag) => flag.to_string(),
Json::String(text) => text.clone(),
Json::Number(number) if number.fract() == 0.0 && number.abs() < 1e15 => {
(*number as i64).to_string()
}
Json::Number(number) => number.to_string(),
other => other.to_string(),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn emptiness_of_every_kind_is_falsy() {
assert!(!truthy(&Json::Null));
assert!(!truthy(&Json::Bool(false)));
assert!(!truthy(&Json::Number(0.0)));
assert!(!truthy(&Json::from("")));
assert!(!truthy(&Json::Array(Vec::new())));
assert!(!truthy(&Json::object(Vec::<(String, Json)>::new())));
assert!(truthy(&Json::Bool(true)));
assert!(truthy(&Json::Number(-1.0)));
assert!(truthy(&Json::from("0")));
assert!(truthy(&Json::from(vec![1])));
}
#[test]
fn only_matching_kinds_are_ordered() {
assert_eq!(compare(&Json::from(1), &Json::from(2)), Some(Ordering::Less));
assert_eq!(compare(&Json::from("a"), &Json::from("b")), Some(Ordering::Less));
assert_eq!(compare(&Json::from(1), &Json::from("1")), None);
}
#[test]
fn null_renders_as_nothing_and_integers_keep_their_shape() {
assert_eq!(to_text(&Json::Null), "");
assert_eq!(to_text(&Json::from(42)), "42");
assert_eq!(to_text(&Json::from(1.5)), "1.5");
assert_eq!(to_text(&Json::Bool(true)), "true");
assert_eq!(to_text(&Json::from(vec![1, 2])), "[1,2]");
}
}