use std::sync::{Arc, Mutex};
use mumu::parser::types::{FunctionValue, IteratorHandle, IteratorKind, PluginIterator, Value};
pub trait LldpEngine: Send + Sync {
fn next(&mut self) -> Result<Value, String>;
}
pub struct LldpIter {
engine: Box<dyn LldpEngine + Send + Sync + 'static>,
}
impl LldpIter {
pub fn new(engine: Box<dyn LldpEngine + Send + Sync + 'static>) -> Self {
Self { engine }
}
}
impl PluginIterator for LldpIter {
#[inline]
fn next_value(&mut self) -> Result<Value, String> {
self.engine.next()
}
}
pub fn iter_to_transform(handle: IteratorHandle) -> Box<FunctionValue> {
use mumu::parser::types::FunctionValue::RustClosure;
Box::new(RustClosure(
"net:lldp-transform".to_string(),
Arc::new(Mutex::new(
move |_interp: &mut mumu::parser::interpreter::Interpreter, _args: Vec<Value>| {
match &handle.kind {
IteratorKind::Core(state_arc) => {
let mut s = state_arc
.lock()
.map_err(|_| "net:lldp-transform: IteratorState lock".to_string())?;
if s.done || s.current >= s.end {
s.done = true;
Err("NO_MORE_DATA".to_string())
} else {
let v = Value::Int(s.current);
s.current += 1;
if s.current >= s.end {
s.done = true;
}
Ok(v)
}
}
IteratorKind::Plugin(p) => {
let mut it = p
.lock()
.map_err(|_| "net:lldp-transform: Plugin Iterator lock".to_string())?;
it.next_value()
}
}
},
)),
0,
))
}
pub(super) fn handle_from_engine(
engine: Box<dyn LldpEngine + Send + Sync + 'static>,
) -> IteratorHandle {
let it = LldpIter::new(engine);
IteratorHandle {
kind: IteratorKind::Plugin(Arc::new(Mutex::new(it))),
}
}