use nlink::netlink::reflector::ReflectExt;
use nlink::netlink::resync::{ResyncMarker, ResyncedEvent};
use nlink::{Store, StoreOp};
use tokio_stream::StreamExt;
#[derive(Clone, Debug)]
enum IfaceEvent {
Added { index: u32, name: &'static str },
Removed { index: u32 },
}
#[tokio::main]
async fn main() -> nlink::Result<()> {
let store: Store<u32, IfaceEvent> = Store::new();
let reader = store.clone();
let events = vec![
Ok(ResyncedEvent::Event(IfaceEvent::Added { index: 1, name: "eth0" })),
Ok(ResyncedEvent::Event(IfaceEvent::Added { index: 2, name: "eth1" })),
Ok(ResyncedEvent::Event(IfaceEvent::Removed { index: 2 })),
Ok(ResyncedEvent::Marker(ResyncMarker::ResyncStart)),
Ok(ResyncedEvent::Resynced(IfaceEvent::Added { index: 1, name: "eth0" })),
Ok(ResyncedEvent::Resynced(IfaceEvent::Added { index: 3, name: "wg0" })),
Ok(ResyncedEvent::Marker(ResyncMarker::ResyncEnd)),
];
let mut watch = tokio_stream::iter(events).reflect(store, |ev| match ev {
IfaceEvent::Added { index, .. } => StoreOp::Upsert(*index),
IfaceEvent::Removed { index } => StoreOp::Remove(*index),
});
while let Some(item) = watch.next().await {
if let Ok(ResyncedEvent::Marker(m)) = &item {
println!("-- marker: {m:?} (store now {} entries)", reader.len());
}
}
println!("\nfinal cache ({} interfaces):", reader.len());
for (idx, ev) in reader.snapshot() {
if let IfaceEvent::Added { name, .. } = ev {
println!(" if{idx} -> {name}");
}
}
assert_eq!(reader.len(), 2);
assert!(reader.contains_key(&1) && reader.contains_key(&3));
assert!(!reader.contains_key(&2));
println!(
"\nReal wiring (root + a live socket):\n \
let store: Store<u32, NetworkEvent> = Store::new();\n \
let watch = conn.into_events_with_resync(factory)?\n \
.reflect(store.clone(), |ev| match ev {{\n \
NetworkEvent::NewLink(l) => StoreOp::Upsert(l.ifindex()),\n \
NetworkEvent::DelLink(l) => StoreOp::Remove(l.ifindex()),\n \
_ => StoreOp::Ignore,\n \
}});\n \
tokio::spawn(async move {{ let mut w = watch; while w.next().await.is_some() {{}} }});\n \
// …then read `store` from anywhere."
);
Ok(())
}