graphrefly_operators/lib.rs
1//! Built-in operator node types for `GraphReFly`.
2//!
3//! Operators in this crate are specialized node types implemented
4//! directly against the Core protocol — they are not "user fns wrapped
5//! in nodes." A `map` operator's plumbing (dirty propagation, equals
6//! dedup, batch handling) runs entirely in Rust; only the user-supplied
7//! `(T) -> U` callback crosses the FFI boundary on each fire.
8//!
9//! # Status (Slice C-3, 2026-05-06)
10//!
11//! Transform module: [`map`], [`filter`], [`scan`], [`reduce`],
12//! [`distinct_until_changed`], [`pairwise`] (Slice C-1, D009–D019).
13//! Combine module: [`combine_latest`], [`merge`], [`with_latest_from`]
14//! (Slice C-2, D020–D023). Flow module: [`take`], [`skip`],
15//! [`take_while`], [`last`], [`last_with_default`] + [`first`],
16//! [`find`], [`element_at`] sugar (Slice C-3, D024–D029). Per-operator
17//! state lives behind a generic
18//! [`OperatorScratch`](graphrefly_core::op_state::OperatorScratch)
19//! slot on `NodeRecord` (D026 — replaces the typed `operator_state`
20//! field used by Slices C-1 / C-2).
21//!
22//! # Module layout (planned)
23//!
24//! - [`transform`] — map, filter, scan, reduce, distinctUntilChanged,
25//! pairwise (✅ Slice C-1)
26//! - [`combine`] — combine, merge, withLatestFrom (✅ Slice C-2)
27//! - [`flow`] — take, skip, takeWhile, last + first/find/element_at
28//! sugar (✅ Slice C-3)
29//! - `temporal` — throttle, debounce, sample
30//! - `switching` — switchMap, mergeMap, concatMap
31//! - `gating` — valve, gate, budgetGate, policyGate
32//! - `resilience` — retry, circuitBreaker, timeout, fallback,
33//! rateLimiter, tokenBucket
34//!
35//! # Layering
36//!
37//! This crate depends on `graphrefly-core` only (per the user-direction
38//! constraint that operators do not depend on `graphrefly-graph`).
39//! Operator factories accept `&Core` directly. User callbacks travel
40//! through the [`OperatorBinding`] super-trait of `BindingBoundary`,
41//! which the binding crate (e.g., a `TestOperatorBinding` for tests, the
42//! napi-rs / pyo3 bindings in production) implements.
43
44#![forbid(unsafe_code)]
45#![warn(rust_2018_idioms, unreachable_pub)]
46#![warn(clippy::pedantic)]
47#![allow(
48 clippy::module_name_repetitions,
49 clippy::missing_errors_doc,
50 clippy::missing_panics_doc,
51 clippy::doc_markdown
52)]
53
54pub mod binding;
55pub mod combine;
56pub mod error;
57pub mod flow;
58pub mod higher_order;
59pub mod ops_impl;
60pub mod producer;
61pub mod transform;
62
63pub use binding::OperatorBinding;
64pub use combine::{combine as combine_latest, merge, with_latest_from, MergeRegistration};
65pub use error::OperatorFactoryError;
66pub use flow::{
67 element_at, find, first, last, last_with_default, skip, take, take_while, FlowRegistration,
68};
69pub use higher_order::{
70 concat_map, exhaust_map, merge_map, merge_map_with_concurrency, switch_map, HigherOrderBinding,
71 ProjectFn,
72};
73pub use ops_impl::{concat, race, take_until, zip};
74pub use producer::{
75 default_producer_deactivate, ProducerBinding, ProducerBuildFn, ProducerCtx, ProducerNodeState,
76 ProducerStorage,
77};
78pub use transform::{
79 distinct_until_changed, filter, map, pairwise, reduce, scan, OperatorRegistration,
80};