use std::any::TypeId;
use crate::runtime::chain_segment::ChainSegmentFactory;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ChainOperatorKind {
Source,
Map,
Filter,
FlatMap,
Sink,
}
pub struct ChainStep {
pub kind: ChainOperatorKind,
pub user_name: Option<String>,
pub factory: ChainSegmentFactory,
}
pub struct ChainJob {
pub parallelism: usize,
pub steps: Vec<ChainStep>,
pub frozen: bool,
pub output_type: Option<TypeId>,
}
impl ChainJob {
pub fn new(parallelism: usize) -> Self {
Self {
parallelism,
steps: Vec::new(),
frozen: false,
output_type: None,
}
}
pub fn push_step_with_types(
&mut self,
step: ChainStep,
input_type: Option<TypeId>,
output_type: TypeId,
) {
if self.frozen {
panic!("chain is frozen after terminal sink");
}
if cfg!(debug_assertions)
&& let (Some(expected_in), Some(prev_out)) = (input_type, self.output_type)
{
assert_eq!(
prev_out, expected_in,
"chain type mismatch at step {:?}: previous output {:?} != expected input {:?}",
step.kind, prev_out, expected_in
);
}
self.output_type = Some(output_type);
let is_sink = step.kind == ChainOperatorKind::Sink;
self.steps.push(step);
if is_sink {
self.frozen = true;
}
}
}