extern crate std;
use nanojson::{Serialize, Serializer, SerializeError, Write, Parser};
#[derive(Debug, PartialEq)]
enum Tree {
Int(i64),
Array(std::vec::Vec<Tree>),
}
impl Tree {
fn nested(depth: usize, n: i64) -> Self {
let mut node = Tree::Int(n);
for _ in 0..depth {
node = Tree::Array(std::vec![node]);
}
node
}
fn leaf_count(&self) -> usize {
match self {
Tree::Int(_) => 1,
Tree::Array(children) => children.iter().map(|c| c.leaf_count()).sum(),
}
}
}
fn write_tree<W: Write, const DEPTH: usize>(
tree: &Tree,
s: &mut Serializer<W, DEPTH>,
) -> Result<(), SerializeError<W::Error>> {
match tree {
Tree::Int(n) => s.integer(*n),
Tree::Array(children) => {
s.array_begin()?;
for child in children {
write_tree(child, s)?;
}
s.array_end()
}
}
}
impl Serialize for Tree {
fn serialize<W: Write>(
&self,
s: &mut Serializer<W>,
) -> Result<(), SerializeError<W::Error>> {
write_tree(self, s)
}
}
#[derive(Debug)]
enum ParseTreeError {
Json(nanojson::ParseError),
NestingTooDeep { limit: usize },
}
impl From<nanojson::ParseError> for ParseTreeError {
fn from(e: nanojson::ParseError) -> Self {
ParseTreeError::Json(e)
}
}
fn parse_tree(
parser: &mut Parser,
current_depth: usize,
max_depth: usize,
) -> Result<Tree, ParseTreeError> {
if current_depth > max_depth {
return Err(ParseTreeError::NestingTooDeep { limit: max_depth });
}
if parser.is_array_ahead() {
parser.array_begin()?;
let mut children = std::vec::Vec::new();
while parser.array_item()? {
children.push(parse_tree(parser, current_depth + 1, max_depth)?);
}
parser.array_end()?;
Ok(Tree::Array(children))
} else {
let n: i64 = parser.number_str()?.parse().unwrap_or(0);
Ok(Tree::Int(n))
}
}
fn main() {
let shallow = Tree::nested(5, 42);
let json = nanojson::stringify(&shallow).unwrap();
std::println!("Shallow tree (5 deep): {json}");
let deep = Tree::nested(50, 7);
match nanojson::stringify(&deep) {
Err(SerializeError::DepthExceeded) => {
std::println!("\nDeep tree (50 levels) via `stringify`: DepthExceeded.");
std::println!(" The `Serialize` trait uses Serializer<W, 32> (the default).");
}
Ok(json) => std::println!(" Unexpectedly succeeded: {} bytes", json.len()),
Err(e) => std::println!(" Unexpected error: {e:?}"),
}
{
let mut ser: Serializer<std::vec::Vec<u8>, 64> =
Serializer::new(std::vec::Vec::new());
write_tree(&deep, &mut ser).unwrap();
let vec = ser.into_writer();
let json = std::string::String::from_utf8(vec).unwrap();
std::println!("\nDeep tree (50 levels) with DEPTH=64: {} bytes serialized.", json.len());
}
let very_deep = Tree::nested(200, 1);
{
let mut ser: Serializer<std::vec::Vec<u8>, 256> =
Serializer::new(std::vec::Vec::new());
match write_tree(&very_deep, &mut ser) {
Ok(()) => {
let len = ser.into_writer().len();
std::println!("Very deep tree (200 levels) with DEPTH=256: {len} bytes.");
}
Err(SerializeError::DepthExceeded) => std::println!("Still too deep."),
Err(e) => std::println!("Error: {e:?}"),
}
}
let src_10 = nanojson::stringify(&Tree::nested(10, 99)).unwrap();
std::println!("\nSource JSON (10 deep, first 40 chars): {:.40}...", &src_10);
let mut buf = [0u8; 1024];
let mut parser = Parser::new(src_10.as_bytes(), &mut buf);
match parse_tree(&mut parser, 0, 20) {
Ok(tree) => std::println!(
"Parsed (limit=20, actual depth=10): {} leaf/leaves found.",
tree.leaf_count()
),
Err(e) => std::println!("Error: {e:?}"),
}
let mut parser = Parser::new(src_10.as_bytes(), &mut buf);
match parse_tree(&mut parser, 0, 5) {
Ok(_) => std::println!("Unexpectedly parsed."),
Err(ParseTreeError::NestingTooDeep { limit }) => {
std::println!("Parse failed: NestingTooDeep (limit={limit}, actual depth=10).");
}
Err(ParseTreeError::Json(e)) => std::println!("JSON error: {e:?}"),
}
let fitting = Tree::nested(30, 5);
let json = nanojson::stringify(&fitting).unwrap();
let mut parser = Parser::new(json.as_bytes(), &mut buf);
let parsed = parse_tree(&mut parser, 0, 32).unwrap();
assert_eq!(parsed.leaf_count(), 1);
std::println!("\nRound-trip (30 deep, default limits): OK.");
}
#[cfg(test)] #[test] fn test_main() { main() }