use std::{collections::HashMap, fmt};
use rkyv::{access, rancor::Error, Archive, Deserialize, Serialize};
#[derive(Archive, Debug, Deserialize, Serialize)]
#[rkyv(serialize_bounds(
__S: rkyv::ser::Writer + rkyv::ser::Allocator,
__S::Error: rkyv::rancor::Source,
))]
#[rkyv(deserialize_bounds(__D::Error: rkyv::rancor::Source))]
#[rkyv(bytecheck(
bounds(
__C: rkyv::validation::ArchiveContext,
)
))]
pub enum JsonValue {
Null,
Bool(bool),
Number(JsonNumber),
String(String),
Array(#[rkyv(omit_bounds)] Vec<JsonValue>),
Object(#[rkyv(omit_bounds)] HashMap<String, JsonValue>),
}
impl fmt::Display for ArchivedJsonValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Null => write!(f, "null")?,
Self::Bool(b) => write!(f, "{}", b)?,
Self::Number(n) => write!(f, "{}", n)?,
Self::String(s) => write!(f, "{}", s)?,
Self::Array(a) => {
write!(f, "[")?;
for (i, value) in a.iter().enumerate() {
write!(f, "{}", value)?;
if i < a.len() - 1 {
write!(f, ", ")?;
}
}
write!(f, "]")?;
}
Self::Object(h) => {
write!(f, "{{")?;
for (i, (key, value)) in h.iter().enumerate() {
write!(f, "\"{}\": {}", key, value)?;
if i < h.len() - 1 {
write!(f, ", ")?;
}
}
write!(f, "}}")?;
}
}
Ok(())
}
}
#[derive(Archive, Debug, Deserialize, Serialize)]
pub enum JsonNumber {
PosInt(u64),
NegInt(i64),
Float(f64),
}
impl fmt::Display for ArchivedJsonNumber {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::PosInt(n) => write!(f, "{}", n),
Self::NegInt(n) => write!(f, "{}", n),
Self::Float(n) => write!(f, "{}", n),
}
}
}
fn main() {
let mut hash_map = HashMap::new();
hash_map.insert("name".into(), JsonValue::String("ferris".into()));
hash_map.insert("age".into(), JsonValue::Number(JsonNumber::PosInt(10)));
hash_map.insert("is_crab".into(), JsonValue::Bool(true));
hash_map.insert("project".into(), JsonValue::Null);
let value = JsonValue::Object(hash_map);
let buf = rkyv::to_bytes::<Error>(&value).unwrap();
let archived_value = access::<ArchivedJsonValue, Error>(&buf).unwrap();
println!("{}", archived_value);
}