mod smooth;
use crate::error::Error;
use std::fmt;
use std::sync::Arc;
use std::sync::Mutex;
use ferrin_tool::ToolSet;
use tokio_util::sync::CancellationToken;
use super::result::EventStream;
pub use smooth::ChunkDetector;
pub use smooth::Chunking;
pub use smooth::SmoothStream;
pub use smooth::SmoothStreamConfig;
pub use smooth::smooth_stream;
#[derive(Clone)]
pub struct TransformContext {
tools: Arc<ToolSet>,
cancellation: CancellationToken,
stop: CancellationToken,
failure: Arc<Mutex<Option<Error>>>,
}
impl TransformContext {
pub(crate) fn new(tools: Arc<ToolSet>, cancellation: CancellationToken) -> Self {
Self {
tools,
cancellation,
stop: CancellationToken::new(),
failure: Arc::new(Mutex::new(None)),
}
}
pub(crate) fn stop_token(&self) -> CancellationToken {
self.stop.clone()
}
pub(crate) fn take_failure(&self) -> Option<Error> {
self.failure
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.take()
}
pub(crate) fn cancellation(&self) -> &CancellationToken {
&self.cancellation
}
pub fn fail(&self, error: Error) {
let mut failure = self
.failure
.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner);
if failure.is_none() {
*failure = Some(error);
}
drop(failure);
self.stop();
}
#[must_use]
pub fn tools(&self) -> &ToolSet {
&self.tools
}
pub fn stop(&self) {
self.stop.cancel();
self.cancellation.cancel();
}
}
impl fmt::Debug for TransformContext {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TransformContext")
.field("tools", &self.tools.names().collect::<Vec<_>>())
.field("stopped", &self.stop.is_cancelled())
.finish()
}
}
pub trait StreamTransform: Send + Sync {
fn apply(&self, input: EventStream, ctx: TransformContext) -> EventStream;
}
impl<F> StreamTransform for F
where
F: Fn(EventStream, TransformContext) -> EventStream + Send + Sync,
{
fn apply(&self, input: EventStream, ctx: TransformContext) -> EventStream {
self(input, ctx)
}
}