use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use anyhow::Result;
use reblessive::tree::Stk;
use crate::ctx::FrozenContext;
use crate::dbs::Options;
use crate::doc::CursorDoc;
use crate::fnc::args::Any;
use crate::val::closure::BuiltinClosureObj;
use crate::val::{BoxInvokeFut, Closure, ClosureEvaluator, Value};
pub(crate) type BuiltinClosureFn = Box<
dyn for<'a> Fn(
&'a mut Stk,
&'a FrozenContext,
&'a Options,
Option<&'a CursorDoc>,
Any,
) -> Pin<Box<dyn Future<Output = Result<Value>> + 'a>>
+ Send
+ Sync,
>;
pub(crate) struct NativeClosure(pub(crate) BuiltinClosureFn);
impl NativeClosure {
pub(crate) fn new_obj(f: BuiltinClosureFn) -> Arc<dyn BuiltinClosureObj> {
Arc::new(NativeClosure(f))
}
}
impl BuiltinClosureObj for NativeClosure {
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
pub(crate) struct LegacyClosureEvaluator<'a> {
ctx: &'a FrozenContext,
opt: &'a Options,
doc: Option<&'a CursorDoc>,
}
impl<'a> LegacyClosureEvaluator<'a> {
pub(crate) fn new(
ctx: &'a FrozenContext,
opt: &'a Options,
doc: Option<&'a CursorDoc>,
) -> Self {
Self {
ctx,
opt,
doc,
}
}
}
impl ClosureEvaluator for LegacyClosureEvaluator<'_> {
fn invoke<'a>(
&'a self,
stk: &'a mut Stk,
closure: &'a Closure,
args: Vec<Value>,
) -> BoxInvokeFut<'a> {
Box::pin(crate::legacy::closure_invoke(closure, stk, self.ctx, self.opt, self.doc, args))
}
}