use std::sync::Arc;
use graphrefly_core::{Core, FnId, HandleId, NodeId, OperatorOp, OperatorOpts};
use crate::binding::OperatorBinding;
#[derive(Copy, Clone, Debug)]
#[must_use = "the operator's NodeId is the value of registering it"]
pub struct OperatorRegistration {
pub node: NodeId,
pub fn_id: FnId,
}
impl OperatorRegistration {
#[must_use]
pub fn into_node(self) -> NodeId {
self.node
}
}
impl From<OperatorRegistration> for NodeId {
fn from(r: OperatorRegistration) -> Self {
r.node
}
}
pub fn map<F>(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
source: NodeId,
project: F,
) -> OperatorRegistration
where
F: Fn(HandleId) -> HandleId + Send + Sync + 'static,
{
map_with(core, binding, source, project, OperatorOpts::default())
}
pub fn map_with<F>(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
source: NodeId,
project: F,
opts: OperatorOpts,
) -> OperatorRegistration
where
F: Fn(HandleId) -> HandleId + Send + Sync + 'static,
{
let fn_id = binding.register_projector(Box::new(project));
let node = core
.register_operator(&[source], OperatorOp::Map { fn_id }, opts)
.expect(
"invariant: caller has validated dep ids and seed before calling register_operator",
);
OperatorRegistration { node, fn_id }
}
pub fn filter<F>(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
source: NodeId,
predicate: F,
) -> OperatorRegistration
where
F: Fn(HandleId) -> bool + Send + Sync + 'static,
{
filter_with(core, binding, source, predicate, OperatorOpts::default())
}
pub fn filter_with<F>(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
source: NodeId,
predicate: F,
opts: OperatorOpts,
) -> OperatorRegistration
where
F: Fn(HandleId) -> bool + Send + Sync + 'static,
{
let fn_id = binding.register_predicate(Box::new(predicate));
let node = core
.register_operator(&[source], OperatorOp::Filter { fn_id }, opts)
.expect(
"invariant: caller has validated dep ids and seed before calling register_operator",
);
OperatorRegistration { node, fn_id }
}
pub fn scan<F>(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
source: NodeId,
fold: F,
seed: HandleId,
) -> OperatorRegistration
where
F: Fn(HandleId, HandleId) -> HandleId + Send + Sync + 'static,
{
scan_with(core, binding, source, fold, seed, OperatorOpts::default())
}
pub fn scan_with<F>(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
source: NodeId,
fold: F,
seed: HandleId,
opts: OperatorOpts,
) -> OperatorRegistration
where
F: Fn(HandleId, HandleId) -> HandleId + Send + Sync + 'static,
{
let fn_id = binding.register_folder(Box::new(fold));
let node = core
.register_operator(&[source], OperatorOp::Scan { fn_id, seed }, opts)
.expect(
"invariant: caller has validated dep ids and seed before calling register_operator",
);
OperatorRegistration { node, fn_id }
}
pub fn reduce<F>(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
source: NodeId,
fold: F,
seed: HandleId,
) -> OperatorRegistration
where
F: Fn(HandleId, HandleId) -> HandleId + Send + Sync + 'static,
{
reduce_with(core, binding, source, fold, seed, OperatorOpts::default())
}
pub fn reduce_with<F>(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
source: NodeId,
fold: F,
seed: HandleId,
opts: OperatorOpts,
) -> OperatorRegistration
where
F: Fn(HandleId, HandleId) -> HandleId + Send + Sync + 'static,
{
let fn_id = binding.register_folder(Box::new(fold));
let node = core
.register_operator(&[source], OperatorOp::Reduce { fn_id, seed }, opts)
.expect(
"invariant: caller has validated dep ids and seed before calling register_operator",
);
OperatorRegistration { node, fn_id }
}
pub fn distinct_until_changed<F>(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
source: NodeId,
equals: F,
) -> OperatorRegistration
where
F: Fn(HandleId, HandleId) -> bool + Send + Sync + 'static,
{
distinct_until_changed_with(core, binding, source, equals, OperatorOpts::default())
}
pub fn distinct_until_changed_with<F>(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
source: NodeId,
equals: F,
opts: OperatorOpts,
) -> OperatorRegistration
where
F: Fn(HandleId, HandleId) -> bool + Send + Sync + 'static,
{
let equals_fn_id = binding.register_equals(Box::new(equals));
let node = core
.register_operator(
&[source],
OperatorOp::DistinctUntilChanged { equals_fn_id },
opts,
)
.expect(
"invariant: caller has validated dep ids and seed before calling register_operator",
);
OperatorRegistration {
node,
fn_id: equals_fn_id,
}
}
pub fn pairwise<F>(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
source: NodeId,
pack: F,
) -> OperatorRegistration
where
F: Fn(HandleId, HandleId) -> HandleId + Send + Sync + 'static,
{
pairwise_with(core, binding, source, pack, OperatorOpts::default())
}
pub fn pairwise_with<F>(
core: &Core,
binding: &Arc<dyn OperatorBinding>,
source: NodeId,
pack: F,
opts: OperatorOpts,
) -> OperatorRegistration
where
F: Fn(HandleId, HandleId) -> HandleId + Send + Sync + 'static,
{
let fn_id = binding.register_pairwise_packer(Box::new(pack));
let node = core
.register_operator(&[source], OperatorOp::Pairwise { fn_id }, opts)
.expect(
"invariant: caller has validated dep ids and seed before calling register_operator",
);
OperatorRegistration { node, fn_id }
}