flow-graph-interpreter 0.22.0

An intepreter for flow-based programs
Documentation
use flow_graph::PortReference;
use wick_packet::Packet;

mod port_buffer;
pub(crate) mod port_handler;

use self::port_handler::PortHandler;
use crate::graph::types::OperationPort;
use crate::interpreter::executor::error::ExecutionError;
type Result<T> = std::result::Result<T, ExecutionError>;
type PacketType = Packet;

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub(crate) enum PortStatus {
  Open,
  DoneClosing,
  DoneClosed,
  UpstreamComplete,
}

impl PortStatus {
  #[allow(unused)]
  #[must_use]
  pub(crate) const fn is_open(self) -> bool {
    !matches!(self, PortStatus::DoneClosed)
  }
  #[allow(unused)]
  #[must_use]
  pub(crate) const fn is_closed(self) -> bool {
    matches!(self, PortStatus::DoneClosed)
  }

  #[allow(unused)]
  #[must_use]
  pub(crate) const fn is_done(self) -> bool {
    matches!(self, PortStatus::DoneClosed | PortStatus::DoneClosing)
  }
}

impl std::fmt::Display for PortStatus {
  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    write!(
      f,
      "{}",
      match self {
        PortStatus::Open => "Open",
        PortStatus::DoneClosing => "DoneClosing",
        PortStatus::DoneClosed => "DoneClosed",
        PortStatus::UpstreamComplete => "UpstreamComplete",
      }
    )
  }
}

#[derive(Debug)]
#[must_use]
pub(crate) struct PortList {
  inner: Vec<PortHandler>,
}

#[allow(unused)]
impl PortList {
  pub(super) fn new<T: Into<String>>(operation_instance: T, ports: Vec<OperationPort>) -> Self {
    let instance = operation_instance.into();
    let ports = ports
      .into_iter()
      .map(|p| PortHandler::new(instance.clone(), p))
      .collect();
    Self { inner: ports }
  }

  pub(crate) fn refs(&self) -> impl Iterator<Item = PortReference> + '_ {
    self.inner.iter().map(|p| p.port_ref())
  }

  #[allow(unused)]
  pub(crate) fn len(&self) -> usize {
    self.inner.len()
  }

  pub(crate) fn is_empty(&self) -> bool {
    self.inner.is_empty()
  }

  pub(super) fn receive(&self, port: &PortReference, value: PacketType) {
    self.inner[port.port_index()].buffer(value);
  }

  pub(super) fn take(&self, port: &PortReference) -> Option<PacketType> {
    self.inner[port.port_index()].take()
  }

  pub(super) fn get_handler(&self, port: &PortReference) -> &PortHandler {
    &self.inner[port.port_index()]
  }

  pub(crate) fn find_ref(&self, name: &str) -> Option<PortReference> {
    for handler in &self.inner {
      if handler.name() == name {
        return Some(handler.port_ref());
      }
    }
    None
  }
}

#[derive(Debug)]
#[must_use]
pub(crate) struct OutputPorts {
  inner: PortList,
}

#[allow(unused)]
impl OutputPorts {
  pub(super) fn new<T: Into<String>>(operation_instance: T, ports: Vec<OperationPort>) -> Self {
    Self {
      inner: PortList::new(operation_instance, ports),
    }
  }

  pub(crate) fn refs(&self) -> impl Iterator<Item = PortReference> + '_ {
    self.inner.refs()
  }

  pub(crate) fn len(&self) -> usize {
    self.inner.inner.len()
  }

  pub(super) fn receive(&self, port: &PortReference, value: PacketType) {
    self.inner.receive(port, value);
  }

  pub(super) fn take(&self, port: &PortReference) -> Option<PacketType> {
    self.inner.take(port)
  }

  pub(crate) fn iter(&self) -> impl Iterator<Item = &PortHandler> {
    self.inner.inner.iter()
  }

  pub(super) fn get_handler(&self, port: &PortReference) -> &PortHandler {
    self.inner.get_handler(port)
  }

  pub(crate) fn find_ref(&self, name: &str) -> Option<PortReference> {
    self.inner.find_ref(name)
  }
}

#[derive(Debug)]
#[must_use]
pub(crate) struct InputPorts {
  inner: PortList,
}

#[allow(unused)]
impl InputPorts {
  pub(super) fn new<T: Into<String>>(operation_instance: T, ports: Vec<OperationPort>) -> Self {
    Self {
      inner: PortList::new(operation_instance, ports),
    }
  }

  pub(crate) fn is_empty(&self) -> bool {
    self.inner.is_empty()
  }

  pub(super) fn receive(&self, port: &PortReference, value: PacketType) {
    self.inner.receive(port, value);
  }

  pub(super) fn take(&self, port: &PortReference) -> Option<PacketType> {
    self.inner.take(port)
  }

  pub(crate) fn iter(&self) -> impl Iterator<Item = &PortHandler> {
    self.inner.inner.iter()
  }

  #[allow(unused)]
  pub(crate) fn len(&self) -> usize {
    self.inner.inner.len()
  }

  pub(super) fn get_handler(&self, port: &PortReference) -> &PortHandler {
    self.inner.get_handler(port)
  }

  pub(crate) fn find_ref(&self, name: &str) -> Option<PortReference> {
    self.inner.find_ref(name)
  }

  pub(super) fn drain_packets(&self) -> Result<Vec<Packet>> {
    let mut vec = Vec::new();

    for handler in &self.inner.inner {
      let mut drain = handler.drain(0..);
      vec.append(&mut drain);
    }
    Ok(vec)
  }
}