use std::sync::{Arc, Mutex};
use mumu::parser::interpreter::Interpreter;
use mumu::parser::types::{FunctionValue, IteratorHandle, IteratorKind, Value};
pub fn is_placeholder(v: &Value) -> bool {
match v {
Value::Placeholder => true,
Value::SingleString(s) if s == "_" => true,
Value::StrArray(ss) if ss.len() == 1 && ss[0] == "_" => true,
_ => false,
}
}
pub fn iter_to_transform(handle: IteratorHandle) -> Box<FunctionValue> {
use FunctionValue::RustClosure;
Box::new(RustClosure(
"flow:iter->transform".to_string(),
Arc::new(Mutex::new(move |_interp: &mut Interpreter, _args: Vec<Value>| {
match &handle.kind {
IteratorKind::Core(state_arc) => {
let mut guard = state_arc
.lock()
.map_err(|_| "flow/common: iterator lock error".to_string())?;
if guard.done || guard.current >= guard.end {
guard.done = true;
Err("NO_MORE_DATA".to_string())
} else {
let item = guard.current;
guard.current += 1;
if guard.current >= guard.end {
guard.done = true;
}
Ok(Value::Int(item))
}
}
IteratorKind::Plugin(plugin_arc) => {
let mut plugin = plugin_arc
.lock()
.map_err(|_| "flow/common: plugin iterator lock error".to_string())?;
match plugin.next_value() {
Ok(v) => Ok(v),
Err(e) => Err(e),
}
}
}
})),
0,
))
}
pub fn to_transform(v: Value) -> Result<Box<FunctionValue>, String> {
match v {
Value::Function(fb) => Ok(fb),
Value::Iterator(h) => Ok(iter_to_transform(h)),
other => Err(format!(
"flow/common: expected Iterator or transform Function, got {:?}",
other
)),
}
}
pub fn once_transform(v: Value) -> Box<FunctionValue> {
use FunctionValue::RustClosure;
let cell = Arc::new(Mutex::new(Some(v)));
Box::new(RustClosure(
"flow:once".to_string(),
Arc::new(Mutex::new(move |_interp: &mut Interpreter, _args: Vec<Value>| {
let mut guard = cell
.lock()
.map_err(|_| "flow/common: once lock error".to_string())?;
match guard.take() {
Some(x) => Ok(x),
None => Err("NO_MORE_DATA".to_string()),
}
})),
0,
))
}