use pack_io::{Deserialize, DeserializeView, Serialize, decode, decode_view, encode};
#[derive(Serialize, Deserialize)]
struct OwnedRecord {
id: u64,
name: String,
payload: Vec<u8>,
tags: Vec<String>,
}
#[derive(DeserializeView)]
struct ViewRecord<'a> {
id: u64,
name: &'a str,
payload: &'a [u8],
tags: Vec<&'a str>,
}
fn main() {
let owned = OwnedRecord {
id: 7,
name: "system.alert.42".into(),
payload: vec![0xab; 128],
tags: vec!["critical".into(), "monitor".into(), "us-east-1".into()],
};
let bytes = encode(&owned).expect("encode");
println!("encoded {} bytes", bytes.len());
let back: OwnedRecord = decode(&bytes).expect("owning decode");
println!(
"\nowning decode: id={} name={:?} payload={}B tags={:?}",
back.id,
back.name,
back.payload.len(),
back.tags
);
let view: ViewRecord<'_> = decode_view(&bytes).expect("view decode");
println!(
"\nzero-copy decode: id={} name={:?} payload={}B tags={:?}",
view.id,
view.name,
view.payload.len(),
view.tags
);
let name_ptr = view.name.as_ptr() as usize;
let buf_start = bytes.as_ptr() as usize;
let buf_end = buf_start + bytes.len();
assert!(name_ptr >= buf_start && name_ptr < buf_end);
println!(
"\nview.name points inside the source buffer at offset {} ✓",
name_ptr - buf_start
);
}