use crate::error::Error;
use crate::node::NodeName;
use otel_arrow_dfe_config::PortName;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum OutputFanoutRule {
#[default]
Unrestricted,
AtMostPerOutput(usize),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct WiringContract {
pub output_fanout: OutputFanoutRule,
}
impl WiringContract {
pub const UNRESTRICTED: Self = Self {
output_fanout: OutputFanoutRule::Unrestricted,
};
#[must_use]
pub const fn unrestricted() -> Self {
Self::UNRESTRICTED
}
#[must_use]
pub const fn at_most_per_output(max: usize) -> Self {
Self {
output_fanout: OutputFanoutRule::AtMostPerOutput(max),
}
}
pub fn validate_output_destinations(
&self,
node: &NodeName,
output: &PortName,
destinations: &[NodeName],
) -> Result<(), Error> {
match self.output_fanout {
OutputFanoutRule::Unrestricted => Ok(()),
OutputFanoutRule::AtMostPerOutput(max) if destinations.len() <= max => Ok(()),
OutputFanoutRule::AtMostPerOutput(max) => Err(Error::InvalidNodeWiring {
node: node.clone(),
output: output.clone(),
max_destinations: max,
actual_destinations: destinations.to_vec(),
}),
}
}
}