use toolkit_zero::serialization::{serializable, serialize, deserialize};
#[serializable]
#[derive(Debug, PartialEq, Clone)]
struct AppConfig {
debug: bool,
max_conn: u32,
hostname: String,
}
#[serializable]
#[derive(Debug, PartialEq, Clone)]
struct Credentials {
pub username: String,
#[serializable(key = "per-field-secret")]
pub password: String,
}
#[serializable]
#[derive(Debug, PartialEq, Clone)]
struct Payload {
id: u64,
data: String,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== serialization macros demo ===\n");
demo_serializable()?;
demo_serializable_field_key()?;
demo_serialize_variable_mode()?;
demo_serialize_file_mode()?;
println!("\nAll demos completed successfully ✓");
Ok(())
}
fn demo_serializable() -> Result<(), Box<dyn std::error::Error>> {
println!("── #[serializable] struct-level round-trips ──────────────────────");
let cfg = AppConfig {
debug: true,
max_conn: 64,
hostname: "localhost".into(),
};
let blob = cfg.seal(None)?;
let recovered = AppConfig::open(&blob, None)?;
assert_eq!(cfg, recovered);
println!(" default key : seal → {} bytes, open → {:?}", blob.len(), recovered);
let blob2 = cfg.seal(Some("my-secret-key".into()))?;
let recovered2 = AppConfig::open(&blob2, Some("my-secret-key".into()))?;
assert_eq!(cfg, recovered2);
println!(" custom key : seal → {} bytes, open → {:?}", blob2.len(), recovered2);
let bad = AppConfig::open(&blob2, Some("wrong-key".into()));
assert!(bad.is_err(), "opening with the wrong key must fail");
println!(" wrong key : open → Err (expected) ✓");
println!();
Ok(())
}
fn demo_serializable_field_key() -> Result<(), Box<dyn std::error::Error>> {
println!("── #[serializable(key = \"...\")] per-field helpers ───────────────");
let creds = Credentials {
username: "alice".into(),
password: "hunter2".into(),
};
let pw_bytes = creds.seal_password()?;
let pw_back = Credentials::open_password(&pw_bytes)?;
assert_eq!("hunter2", pw_back);
println!(" seal_password → {} bytes", pw_bytes.len());
println!(" open_password → {:?}", pw_back);
let full_blob = creds.seal(None)?;
let full_back = Credentials::open(&full_blob, None)?;
assert_eq!(creds, full_back);
println!(" full seal/open → {:?}", full_back);
println!();
Ok(())
}
fn demo_serialize_variable_mode() -> Result<(), Box<dyn std::error::Error>> {
println!("── #[serialize] / #[deserialize] variable mode ─────────────────");
let payload = Payload { id: 42, data: "hello, world".into() };
#[serialize(payload)]
fn blob() -> Vec<u8> {}
#[deserialize(blob)]
fn restored() -> Payload {}
assert_eq!(payload, restored);
println!(" default key : {} bytes → {:?}", blob.len(), restored);
#[serialize(payload, key = "custom-key".to_string())]
fn blob_keyed() -> Vec<u8> {}
#[deserialize(blob_keyed, key = "custom-key".to_string())]
fn restored_keyed() -> Payload {}
assert_eq!(payload, restored_keyed);
println!(" custom key : {} bytes → {:?}", blob_keyed.len(), restored_keyed);
let wrong = toolkit_zero::serialization::open::<Payload, String>(&blob_keyed, None);
assert!(wrong.is_err(), "decrypting with the wrong key must fail");
println!(" wrong key : open → Err (expected) ✓");
println!();
Ok(())
}
fn demo_serialize_file_mode() -> Result<(), Box<dyn std::error::Error>> {
println!("── #[serialize] / #[deserialize] file mode ─────────────────────");
let payload = Payload { id: 99, data: "persisted value".into() };
#[serialize(payload, path = "/tmp/toolkit_zero_demo.bin")]
fn _write() {}
#[deserialize(path = "/tmp/toolkit_zero_demo.bin")]
fn loaded() -> Payload {}
assert_eq!(payload, loaded);
println!(" default key : wrote /tmp/toolkit_zero_demo.bin → {:?}", loaded);
#[serialize(payload, path = "/tmp/toolkit_zero_demo_keyed.bin", key = "file-key".to_string())]
fn _write_keyed() {}
#[deserialize(path = "/tmp/toolkit_zero_demo_keyed.bin", key = "file-key".to_string())]
fn loaded_keyed() -> Payload {}
assert_eq!(payload, loaded_keyed);
println!(" custom key : wrote /tmp/toolkit_zero_demo_keyed.bin → {:?}", loaded_keyed);
std::fs::remove_file("/tmp/toolkit_zero_demo.bin").ok();
std::fs::remove_file("/tmp/toolkit_zero_demo_keyed.bin").ok();
println!();
Ok(())
}