use std::io::{BufReader, BufWriter, Cursor, Write as _};
use ipnet::Ipv4Net;
use prefix_trie::{joint::JointPrefixMap, PrefixMap};
fn export_to_writer<P, T, W>(
map: &PrefixMap<P, T>,
writer: W,
) -> Result<(), Box<dyn std::error::Error>>
where
P: serde::Serialize + prefix_trie::Prefix,
T: serde::Serialize,
W: std::io::Write,
{
let config = bincode::config::standard();
let mut writer = BufWriter::new(writer);
for (prefix, value) in map.iter() {
bincode::serde::encode_into_std_write(&(prefix, value), &mut writer, config)?;
}
writer.flush()?;
Ok(())
}
fn import_from_reader<P, T, R>(reader: R) -> Result<PrefixMap<P, T>, Box<dyn std::error::Error>>
where
P: serde::de::DeserializeOwned + prefix_trie::Prefix,
T: serde::de::DeserializeOwned,
R: std::io::Read,
{
let config = bincode::config::standard();
let mut reader = BufReader::new(reader);
let mut map = PrefixMap::new();
loop {
match bincode::serde::decode_from_std_read::<(P, T), _, _>(&mut reader, config) {
Ok((prefix, value)) => {
map.insert(prefix, value);
}
Err(bincode::error::DecodeError::Io { inner, .. })
if inner.kind() == std::io::ErrorKind::UnexpectedEof =>
{
break; }
Err(e) => return Err(e.into()),
}
}
Ok(map)
}
fn export_joint_to_writer<P, T, W>(
map: &JointPrefixMap<P, T>,
writer: W,
) -> Result<(), Box<dyn std::error::Error>>
where
P: serde::Serialize + prefix_trie::joint::JointPrefix,
T: serde::Serialize,
W: std::io::Write,
{
let config = bincode::config::standard();
let mut writer = BufWriter::new(writer);
for (prefix, value) in map.iter() {
bincode::serde::encode_into_std_write(&(prefix, value), &mut writer, config)?;
}
writer.flush()?;
Ok(())
}
fn import_joint_from_reader<P, T, R>(
reader: R,
) -> Result<JointPrefixMap<P, T>, Box<dyn std::error::Error>>
where
P: serde::de::DeserializeOwned + prefix_trie::joint::JointPrefix,
T: serde::de::DeserializeOwned,
R: std::io::Read,
{
let config = bincode::config::standard();
let mut reader = BufReader::new(reader);
let mut map = JointPrefixMap::new();
loop {
match bincode::serde::decode_from_std_read::<(P, T), _, _>(&mut reader, config) {
Ok((prefix, value)) => {
map.insert(prefix, value);
}
Err(bincode::error::DecodeError::Io { inner, .. })
if inner.kind() == std::io::ErrorKind::UnexpectedEof =>
{
break;
}
Err(e) => return Err(e.into()),
}
}
Ok(map)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut pm: PrefixMap<Ipv4Net, String> = PrefixMap::new();
pm.insert("10.0.0.0/8".parse()?, "backbone".into());
pm.insert("10.1.0.0/16".parse()?, "edge".into());
pm.insert("192.168.1.0/24".parse()?, "lan".into());
let mut buf = Vec::new();
export_to_writer(&pm, &mut buf)?;
println!(
"PrefixMap: serialized {} bytes for {} entries",
buf.len(),
pm.len()
);
let restored = import_from_reader::<Ipv4Net, String, _>(Cursor::new(&buf))?;
assert_eq!(restored.len(), pm.len());
for (prefix, value) in pm.iter() {
assert_eq!(restored.get(&prefix), Some(value));
}
println!("PrefixMap: round-trip OK");
let mut jpm: JointPrefixMap<ipnet::IpNet, u32> = JointPrefixMap::new();
jpm.insert("10.0.0.0/8".parse()?, 100);
jpm.insert("2001:db8::/32".parse()?, 200);
let mut jbuf = Vec::new();
export_joint_to_writer(&jpm, &mut jbuf)?;
println!(
"JointPrefixMap: serialized {} bytes for {} entries",
jbuf.len(),
jpm.len()
);
let jrestored = import_joint_from_reader::<ipnet::IpNet, u32, _>(Cursor::new(&jbuf))?;
assert_eq!(jrestored.len(), jpm.len());
println!("JointPrefixMap: round-trip OK");
Ok(())
}