extern crate std;
use std::collections::HashMap;
use nanojson::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Address {
street: String,
city: String,
zip: String,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Profile {
username: String,
email: String,
address: Address,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Item {
id: i64,
name: String,
price: i64,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Inventory {
items: Vec<Item>,
metadata: HashMap<String, String>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
enum Role {
Admin,
User,
Guest,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
enum Status {
Active,
Disabled,
Pending,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
enum Event {
Login { user_id: i64 },
Purchase { item_id: i64, quantity: i64 },
Logout,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct User {
id: i64,
profile: Box<Profile>, roles: Vec<Role>, status: Status,
tags: Vec<String>, preferences: HashMap<String, String>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct AppState {
users: Vec<User>,
inventory: Inventory,
sessions: HashMap<String, i32>,
events: Vec<Event>,
}
fn main() {
let mut prefs = HashMap::new();
prefs.insert("theme".to_string(), "dark".to_string());
prefs.insert("language".to_string(), "en".to_string());
let mut metadata = HashMap::new();
metadata.insert("warehouse".to_string(), "A1".to_string());
metadata.insert("currency".to_string(), "USD".to_string());
let mut sessions = HashMap::new();
sessions.insert("session_abc".to_string(), 1);
sessions.insert("session_xyz".to_string(), 2);
let state = AppState {
users: vec![
User {
id: 1,
profile: Box::new(Profile {
username: "alice".to_string(),
email: "alice@example.com".to_string(),
address: Address {
street: "Main St".to_string(),
city: "Wonderland".to_string(),
zip: "12345".to_string(),
},
}),
roles: vec![Role::Admin, Role::User],
status: Status::Active,
tags: vec!["premium".to_string(), "beta".to_string()],
preferences: prefs.clone(),
},
User {
id: 2,
profile: Box::new(Profile {
username: "bob".to_string(),
email: "bob@example.com".to_string(),
address: Address {
street: "Second St".to_string(),
city: "Builderland".to_string(),
zip: "67890".to_string(),
},
}),
roles: vec![Role::User],
status: Status::Pending,
tags: vec![],
preferences: prefs.clone(),
},
],
inventory: Inventory {
items: vec![
Item { id: 1, name: "Sword".to_string(), price: 100 },
Item { id: 2, name: "Shield".to_string(), price: 150 },
],
metadata,
},
sessions,
events: vec![
Event::Login { user_id: 1 },
Event::Purchase { item_id: 2, quantity: 1 },
Event::Logout,
],
};
let json = nanojson::stringify_pretty(2, &state).unwrap();
std::println!("AppState JSON:\n{json}");
let decoded: AppState = nanojson::parse(&json).unwrap();
std::println!("\nDecoded:\n{:?}", decoded);
assert_eq!(state, decoded);
let raw = r#"
{
"users": [
{
"id": 3,
"profile": {
"username": "charlie",
"email": "charlie@example.com",
"address": {
"street": "Third St",
"city": "ChocolateFactory",
"zip": "99999"
}
},
"roles": ["Guest"],
"status": "Disabled",
"tags": ["new"],
"preferences": {
"theme": "light"
}
}
],
"inventory": {
"items": [
{ "id": 10, "name": "Potion", "price": 50 }
],
"metadata": {
"warehouse": "B2"
}
},
"sessions": {
"session_foo": 3
},
"events": [
{ "Login": { "user_id": 3 } },
{ "Logout": null }
]
}
"#;
println!("");
match nanojson::parse::<AppState>(raw) {
Ok(parsed) => {
std::println!("\nParsed from raw JSON:\n{:?}", parsed);
}
Err(e) => e.print(raw),
}
}
#[cfg(test)] #[test] fn test_main() { main() }