use std::sync::Arc;
use tokio_util::sync::CancellationToken;
use crate::ctx::Context;
use crate::exec::context::RootContext;
use crate::exec::{
AccessMode, CardinalityHint, ContextLevel, ExecOperator, ExecutionContext, FlowResult,
OutputOrdering, ValueBatch, ValueBatchStream,
};
use crate::iam::Auth;
use crate::val::Value;
#[derive(Debug)]
pub(crate) struct ValuesOperator {
values: Vec<Value>,
cardinality: CardinalityHint,
ordering: OutputOrdering,
}
impl ValuesOperator {
#[allow(clippy::new_ret_no_self)]
pub(crate) fn new(values: Vec<Value>) -> Arc<dyn ExecOperator> {
Arc::new(Self {
values,
cardinality: CardinalityHint::Unbounded,
ordering: OutputOrdering::Unordered,
})
}
}
impl ExecOperator for ValuesOperator {
fn name(&self) -> &'static str {
"Values"
}
fn required_context(&self) -> ContextLevel {
ContextLevel::Root
}
fn access_mode(&self) -> AccessMode {
AccessMode::ReadOnly
}
fn cardinality_hint(&self) -> CardinalityHint {
self.cardinality
}
fn output_ordering(&self) -> OutputOrdering {
self.ordering.clone()
}
fn execute(&self, _ctx: &ExecutionContext) -> FlowResult<ValueBatchStream> {
let values = self.values.clone();
let stream = async_stream::try_stream! {
yield ValueBatch { values };
};
Ok(Box::pin(stream))
}
}
pub(crate) fn root_ctx() -> ExecutionContext {
ExecutionContext::Root(RootContext {
ctx: Context::new_test().freeze(),
options: None,
datastore: None,
cancellation: CancellationToken::new(),
auth: Arc::new(Auth::default()),
session: None,
current_value: None,
skip_fetch_perms: false,
version_stamp: None,
})
}
pub(crate) async fn collect(op: &Arc<dyn ExecOperator>, ctx: &ExecutionContext) -> Vec<Value> {
use futures::StreamExt;
let stream = op.execute(ctx).expect("execute should succeed");
futures::pin_mut!(stream);
let mut out = Vec::new();
while let Some(batch) = stream.next().await {
out.extend(batch.expect("batch should be Ok").values);
}
out
}