use std::sync::Arc;
use graphrefly_core::{Core, FnId, HandleId, NodeId, OperatorOp, OperatorOpts};
use crate::binding::OperatorBinding;
use crate::error::OperatorFactoryError;
use crate::transform::OperatorRegistration;
pub type PackerFn = Box<dyn Fn(&[HandleId]) -> HandleId + Send + Sync>;
pub fn combine(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
sources: &[NodeId],
packer: PackerFn,
) -> Result<OperatorRegistration, OperatorFactoryError> {
if sources.is_empty() {
return Err(OperatorFactoryError::EmptySources);
}
let pack_fn = binding.register_packer(packer);
let opts = OperatorOpts::default(); let node = core.register_operator(sources, OperatorOp::Combine { pack_fn }, opts)?;
Ok(OperatorRegistration {
node,
fn_id: pack_fn,
})
}
pub fn with_latest_from(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
primary: NodeId,
secondary: NodeId,
packer: PackerFn,
) -> OperatorRegistration {
let pack_fn = binding.register_packer(packer);
let opts = OperatorOpts::default(); let node = core
.register_operator(
&[primary, secondary],
OperatorOp::WithLatestFrom { pack_fn },
opts,
)
.expect(
"invariant: caller has validated dep ids and seed before calling register_operator",
);
OperatorRegistration {
node,
fn_id: pack_fn,
}
}
#[derive(Copy, Clone, Debug)]
#[must_use = "the merge operator's NodeId is the value of registering it"]
pub struct MergeRegistration {
pub node: NodeId,
}
impl MergeRegistration {
#[must_use]
pub fn into_node(self) -> NodeId {
self.node
}
}
pub fn merge(core: &Core, sources: &[NodeId]) -> Result<MergeRegistration, OperatorFactoryError> {
if sources.is_empty() {
return Err(OperatorFactoryError::EmptySources);
}
let opts = OperatorOpts {
partial: true, ..OperatorOpts::default()
};
let node = core.register_operator(sources, OperatorOp::Merge, opts)?;
Ok(MergeRegistration { node })
}
pub fn merge_as_op(
core: &Core,
sources: &[NodeId],
) -> Result<OperatorRegistration, OperatorFactoryError> {
let reg = merge(core, sources)?;
Ok(OperatorRegistration {
node: reg.node,
fn_id: FnId::new(0), })
}