use crate::model::record::{OperatorRecord, SinkRecord, SourceRecord};
use crate::prelude::{Configuration, Context, Inputs, Node, Outputs, Result};
use std::ops::Deref;
use std::pin::Pin;
use std::sync::Arc;
use futures::Future;
#[cfg(target_family = "unix")]
use libloading::os::unix::Library;
#[cfg(target_family = "windows")]
use libloading::Library;
pub(crate) struct NodeConstructor<Record, C: ConstructorFn> {
pub(crate) record: Record,
pub(crate) constructor: C,
_library: Option<Arc<Library>>,
}
pub(crate) trait ConstructorFn {}
pub type SourceFn = fn(
Context,
Option<Configuration>,
Outputs,
) -> Pin<Box<dyn Future<Output = Result<Arc<dyn Node>>> + Send>>;
impl ConstructorFn for SourceFn {}
pub type OperatorFn = fn(
Context,
Option<Configuration>,
Inputs,
Outputs,
) -> Pin<Box<dyn Future<Output = Result<Arc<dyn Node>>> + Send>>;
impl ConstructorFn for OperatorFn {}
pub type SinkFn = fn(
Context,
Option<Configuration>,
Inputs,
) -> Pin<Box<dyn Future<Output = Result<Arc<dyn Node>>> + Send>>;
impl ConstructorFn for SinkFn {}
pub(crate) type SourceConstructor = NodeConstructor<SourceRecord, SourceFn>;
pub(crate) type OperatorConstructor = NodeConstructor<OperatorRecord, OperatorFn>;
pub(crate) type SinkConstructor = NodeConstructor<SinkRecord, SinkFn>;
impl<Record, C: ConstructorFn> Deref for NodeConstructor<Record, C> {
type Target = Record;
fn deref(&self) -> &Self::Target {
&self.record
}
}
impl<Record, C: ConstructorFn> NodeConstructor<Record, C> {
pub(crate) fn new_static(record: Record, constructor: C) -> Self {
Self {
record,
constructor,
_library: None,
}
}
pub(crate) fn new_dynamic(record: Record, constructor: C, library: Arc<Library>) -> Self {
Self {
record,
constructor,
_library: Some(library),
}
}
}