hydroflow_plus 0.10.0

Functional programming API for hydroflow
Documentation
use std::marker::PhantomData;

use hydroflow::bytes::Bytes;
use serde::de::DeserializeOwned;
use serde::Serialize;

use super::{Location, LocationId, NoTick};
use crate::builder::FlowState;
use crate::ir::{HfPlusNode, HfPlusSource};
use crate::{Stream, Unbounded};

pub struct ExternalBytesPort {
    pub(crate) process_id: usize,
    pub(crate) port_id: usize,
}

pub struct ExternalBincodeSink<T: Serialize> {
    pub(crate) process_id: usize,
    pub(crate) port_id: usize,
    pub(crate) _phantom: PhantomData<T>,
}

pub struct ExternalBincodeStream<T: DeserializeOwned> {
    pub(crate) process_id: usize,
    pub(crate) port_id: usize,
    pub(crate) _phantom: PhantomData<T>,
}

pub struct ExternalProcess<'a, P> {
    pub(crate) id: usize,

    pub(crate) flow_state: FlowState,

    pub(crate) _phantom: PhantomData<&'a &'a mut P>,
}

impl<P> Clone for ExternalProcess<'_, P> {
    fn clone(&self) -> Self {
        ExternalProcess {
            id: self.id,
            flow_state: self.flow_state.clone(),
            _phantom: PhantomData,
        }
    }
}

impl<'a, P> Location<'a> for ExternalProcess<'a, P> {
    fn id(&self) -> LocationId {
        LocationId::ExternalProcess(self.id)
    }

    fn flow_state(&self) -> &FlowState {
        &self.flow_state
    }

    fn is_top_level() -> bool {
        true
    }
}

impl<'a, P> ExternalProcess<'a, P> {
    pub fn source_external_bytes<L: Location<'a> + NoTick>(
        &self,
        to: &L,
    ) -> (ExternalBytesPort, Stream<Bytes, L, Unbounded>) {
        let next_external_port_id = {
            let mut flow_state = self.flow_state.borrow_mut();
            let id = flow_state.next_external_out;
            flow_state.next_external_out += 1;
            id
        };

        (
            ExternalBytesPort {
                process_id: self.id,
                port_id: next_external_port_id,
            },
            Stream::new(
                to.clone(),
                HfPlusNode::Persist(Box::new(HfPlusNode::Network {
                    from_location: LocationId::ExternalProcess(self.id),
                    from_key: Some(next_external_port_id),
                    to_location: to.id(),
                    to_key: None,
                    serialize_pipeline: None,
                    instantiate_fn: crate::ir::DebugInstantiate::Building(),
                    deserialize_pipeline: Some(syn::parse_quote!(map(|b| b.unwrap().freeze()))),
                    input: Box::new(HfPlusNode::Source {
                        source: HfPlusSource::ExternalNetwork(),
                        location_kind: LocationId::ExternalProcess(self.id),
                    }),
                })),
            ),
        )
    }

    pub fn source_external_bincode<L: Location<'a> + NoTick, T: Serialize + DeserializeOwned>(
        &self,
        to: &L,
    ) -> (ExternalBincodeSink<T>, Stream<T, L, Unbounded>) {
        let next_external_port_id = {
            let mut flow_state = self.flow_state.borrow_mut();
            let id = flow_state.next_external_out;
            flow_state.next_external_out += 1;
            id
        };

        (
            ExternalBincodeSink {
                process_id: self.id,
                port_id: next_external_port_id,
                _phantom: PhantomData,
            },
            Stream::new(
                to.clone(),
                HfPlusNode::Persist(Box::new(HfPlusNode::Network {
                    from_location: LocationId::ExternalProcess(self.id),
                    from_key: Some(next_external_port_id),
                    to_location: to.id(),
                    to_key: None,
                    serialize_pipeline: None,
                    instantiate_fn: crate::ir::DebugInstantiate::Building(),
                    deserialize_pipeline: Some(crate::stream::deserialize_bincode::<T>(None)),
                    input: Box::new(HfPlusNode::Source {
                        source: HfPlusSource::ExternalNetwork(),
                        location_kind: LocationId::ExternalProcess(self.id),
                    }),
                })),
            ),
        )
    }
}