#![feature(offset_of_enum)]
use nearest::{Flat, Near, NearList, Region, list, near};
#[derive(Flat, Debug)]
struct Entry {
key: NearList<u8>,
val: Near<Json>,
}
#[derive(Flat, Debug)]
#[repr(C, u8)]
#[expect(dead_code, reason = "variants constructed via emitters")]
enum Json {
Null,
Bool(bool),
Num(i64),
Str { chars: NearList<u8> },
Arr { items: NearList<Json> },
Obj { fields: NearList<Entry> },
}
fn str_of(list: &NearList<u8>) -> String {
list.iter().map(|&b| b as char).collect()
}
fn pretty(json: &Json, indent: usize) -> String {
let pad = " ".repeat(indent);
match json {
Json::Null => "null".into(),
Json::Bool(b) => b.to_string(),
Json::Num(n) => n.to_string(),
Json::Str { chars } => format!("\"{}\"", str_of(chars)),
Json::Arr { items } => {
if items.is_empty() {
return "[]".into();
}
let inner: Vec<String> =
items.iter().map(|v| format!("{} {}", pad, pretty(v, indent + 1))).collect();
format!("[\n{}\n{}]", inner.join(",\n"), pad)
}
Json::Obj { fields } => {
if fields.is_empty() {
return "{}".into();
}
let inner: Vec<String> = fields
.iter()
.map(|e| format!("{} \"{}\": {}", pad, str_of(&e.key), pretty(&e.val, indent + 1)))
.collect();
format!("{{\n{}\n{}}}", inner.join(",\n"), pad)
}
}
}
fn main() {
let name_val = Region::new(Json::make_str(list(b"Alice".as_slice())));
let age_val = Region::new(Json::make_num(30));
let scores_val =
Region::new(Json::make_arr(list([Json::make_num(95), Json::make_num(87), Json::make_num(92)])));
let mut region = Region::new(Json::make_obj(list([
Entry::make(list(b"name".as_slice()), near(&*name_val)),
Entry::make(list(b"age".as_slice()), near(&*age_val)),
Entry::make(list(b"scores".as_slice()), near(&*scores_val)),
])));
println!("=== original ===");
println!("{}", pretty(®ion, 0));
region.session(|s| {
let fields = s.nav(s.root(), |j| match j {
Json::Obj { fields } => fields,
_ => panic!("expected Obj"),
});
s.extend_list(fields, [Entry::make(list(b"active".as_slice()), near(Json::make_bool(true)))]);
});
println!("\n=== after adding \"active\" ===");
println!("{}", pretty(®ion, 0));
match &*region {
Json::Obj { fields } => {
assert_eq!(fields.len(), 4);
let last = &fields[3];
assert_eq!(str_of(&last.key), "active");
assert!(matches!(&*last.val, Json::Bool(true)));
}
_ => panic!("expected Obj"),
}
let before = region.byte_len();
region.trim();
println!("\ntrim: {} -> {} bytes", before, region.byte_len());
}