// 955: JSON Value Type
// OCaml: type json = Null | Bool of bool | Number of float | Str of string | Array of json list | Object of (string * json) list
// Rust: enum JsonValue with derived traits
// Approach 1: Direct enum translation
#[derive(Debug, Clone, PartialEq)]
pub enum JsonValue {
Null,
Bool(bool),
Number(f64),
Str(String),
Array(Vec<JsonValue>),
Object(Vec<(String, JsonValue)>),
}
// Approach 2: Type checks and simple display
impl JsonValue {
pub fn is_null(&self) -> bool { matches!(self, JsonValue::Null) }
pub fn is_bool(&self) -> bool { matches!(self, JsonValue::Bool(_)) }
pub fn is_number(&self) -> bool { matches!(self, JsonValue::Number(_)) }
pub fn is_string(&self) -> bool { matches!(self, JsonValue::Str(_)) }
pub fn is_array(&self) -> bool { matches!(self, JsonValue::Array(_)) }
pub fn is_object(&self) -> bool { matches!(self, JsonValue::Object(_)) }
pub fn to_string_simple(&self) -> String {
match self {
JsonValue::Null => "null".to_string(),
JsonValue::Bool(true) => "true".to_string(),
JsonValue::Bool(false) => "false".to_string(),
JsonValue::Number(n) => {
if n.fract() == 0.0 && n.is_finite() {
format!("{}", *n as i64)
} else {
format!("{}", n)
}
}
JsonValue::Str(s) => format!("\"{}\"", s),
JsonValue::Array(_) => "[...]".to_string(),
JsonValue::Object(_) => "{...}".to_string(),
}
}
}
// Approach 3: Builder helpers
impl JsonValue {
pub fn object(pairs: &[(&str, JsonValue)]) -> Self {
JsonValue::Object(pairs.iter().map(|(k, v)| (k.to_string(), v.clone())).collect())
}
pub fn array(items: Vec<JsonValue>) -> Self {
JsonValue::Array(items)
}
}
fn main() {
let j_null = JsonValue::Null;
let j_bool = JsonValue::Bool(true);
let j_num = JsonValue::Number(42.0);
let j_str = JsonValue::Str("hello".to_string());
let j_arr = JsonValue::array(vec![
JsonValue::Number(1.0),
JsonValue::Number(2.0),
JsonValue::Number(3.0),
]);
let j_obj = JsonValue::object(&[
("name", JsonValue::Str("Alice".to_string())),
("age", JsonValue::Number(30.0)),
]);
println!("null: {}", j_null.to_string_simple());
println!("bool: {}", j_bool.to_string_simple());
println!("number: {}", j_num.to_string_simple());
println!("string: {}", j_str.to_string_simple());
println!("array: {}", j_arr.to_string_simple());
println!("object: {}", j_obj.to_string_simple());
println!("equal: {}", JsonValue::Bool(true) == JsonValue::Bool(true));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_type_checks() {
assert!(JsonValue::Null.is_null());
assert!(JsonValue::Bool(true).is_bool());
assert!(JsonValue::Number(1.0).is_number());
assert!(JsonValue::Str("x".into()).is_string());
assert!(JsonValue::Array(vec![]).is_array());
assert!(JsonValue::Object(vec![]).is_object());
}
#[test]
fn test_to_string_simple() {
assert_eq!(JsonValue::Null.to_string_simple(), "null");
assert_eq!(JsonValue::Bool(true).to_string_simple(), "true");
assert_eq!(JsonValue::Bool(false).to_string_simple(), "false");
assert_eq!(JsonValue::Number(42.0).to_string_simple(), "42");
assert_eq!(JsonValue::Str("hello".into()).to_string_simple(), "\"hello\"");
assert_eq!(JsonValue::Array(vec![]).to_string_simple(), "[...]");
assert_eq!(JsonValue::Object(vec![]).to_string_simple(), "{...}");
}
#[test]
fn test_equality() {
assert_eq!(JsonValue::Null, JsonValue::Null);
assert_eq!(JsonValue::Bool(true), JsonValue::Bool(true));
assert_ne!(JsonValue::Bool(true), JsonValue::Bool(false));
assert_eq!(JsonValue::Number(1.0), JsonValue::Number(1.0));
let arr1 = JsonValue::Array(vec![JsonValue::Null, JsonValue::Bool(true)]);
let arr2 = JsonValue::Array(vec![JsonValue::Null, JsonValue::Bool(true)]);
assert_eq!(arr1, arr2);
}
#[test]
fn test_nested_object() {
let obj = JsonValue::object(&[
("name", JsonValue::Str("Alice".into())),
("age", JsonValue::Number(30.0)),
("active", JsonValue::Bool(true)),
]);
assert!(obj.is_object());
if let JsonValue::Object(pairs) = &obj {
assert_eq!(pairs.len(), 3);
assert_eq!(pairs[0].0, "name");
}
}
}
(* 955: JSON Value Type *)
(* Approach 1: Algebraic data type definition *)
type json =
| Null
| Bool of bool
| Number of float
| Str of string
| Array of json list
| Object of (string * json) list
(* Approach 2: Constructors and basic operations *)
let to_string_simple j =
match j with
| Null -> "null"
| Bool true -> "true"
| Bool false -> "false"
| Number n ->
if Float.is_integer n then string_of_int (int_of_float n)
else Printf.sprintf "%g" n
| Str s -> Printf.sprintf "\"%s\"" s
| Array _ -> "[...]"
| Object _ -> "{...}"
let is_null = function Null -> true | _ -> false
let is_bool = function Bool _ -> true | _ -> false
let is_number = function Number _ -> true | _ -> false
let is_string = function Str _ -> true | _ -> false
let is_array = function Array _ -> true | _ -> false
let is_object = function Object _ -> true | _ -> false
(* Approach 3: Pattern matching and equality *)
let rec equal a b = match a, b with
| Null, Null -> true
| Bool x, Bool y -> x = y
| Number x, Number y -> x = y
| Str x, Str y -> x = y
| Array xs, Array ys ->
List.length xs = List.length ys &&
List.for_all2 equal xs ys
| Object xs, Object ys ->
List.length xs = List.length ys &&
List.for_all2 (fun (k1,v1) (k2,v2) -> k1 = k2 && equal v1 v2) xs ys
| _ -> false
let () =
let j_null = Null in
let j_bool = Bool true in
let j_num = Number 42.0 in
let j_str = Str "hello" in
let j_arr = Array [Number 1.0; Number 2.0; Number 3.0] in
let j_obj = Object [("name", Str "Alice"); ("age", Number 30.0)] in
assert (is_null j_null);
assert (is_bool j_bool);
assert (is_number j_num);
assert (is_string j_str);
assert (is_array j_arr);
assert (is_object j_obj);
assert (to_string_simple j_null = "null");
assert (to_string_simple j_bool = "true");
assert (to_string_simple j_num = "42");
assert (to_string_simple j_str = "\"hello\"");
assert (equal Null Null);
assert (equal (Bool true) (Bool true));
assert (not (equal (Bool true) (Bool false)));
assert (equal (Number 1.0) (Number 1.0));
assert (equal (Array [Null; Bool true]) (Array [Null; Bool true]));
assert (not (equal (Array [Null]) (Array [Bool true])));
Printf.printf "โ All tests passed\n"