Skip to main content

allora_runtime/spec/
aggregator_spec.rs

1//! `AggregatorSpec`: specification for a single EIP Aggregator instance.
2//!
3//! An aggregator is declared in `allora.yaml` by id; it references consumer-supplied
4//! implementations of [`allora_core::patterns::aggregator::CompletionCondition`],
5//! [`allora_core::patterns::aggregator::AggregationStrategy`], and
6//! [`allora_core::patterns::aggregator::GroupStore`] **by name** — those names resolve
7//! through the runtime [`crate::dsl::PatternRegistry`] at build time.
8//!
9//! # Field Semantics
10//!
11//! * `id` (optional) — explicit identifier for referencing the built aggregator from
12//!   consumer code. If absent, [`crate::dsl::build_aggregators_from_spec`] generates
13//!   a deterministic `aggregator:auto.N` id.
14//! * `correlation_header` (required, non-empty) — header key used to group messages
15//!   (e.g. `"block_hash"` for the chain's finality quorum).
16//! * `completion` (required, non-empty) — registry name of the
17//!   [`allora_core::patterns::aggregator::CompletionCondition`] to use. *No defaults* —
18//!   the chain's quorum logic is registry-supplied, and that's the canonical use case.
19//! * `strategy` (optional, non-empty if present) — registry name of the
20//!   [`allora_core::patterns::aggregator::AggregationStrategy`]. Defaults to
21//!   `allora.concat_text` (matching `Aggregator::new`'s default behavior) at build time.
22//! * `store` (optional, non-empty if present) — registry name of the
23//!   [`allora_core::patterns::aggregator::GroupStore`]. Defaults to an
24//!   `InMemoryGroupStore` instance at build time.
25//!
26//! # Uniqueness & Validation
27//! YAML parser ([`crate::spec::AggregatorSpecYamlParser`]) enforces presence + type +
28//! non-empty strings. Uniqueness of `id` is deferred to the collection builder
29//! ([`crate::dsl::build_aggregators_from_spec`]).
30//!
31//! # Construction Helpers
32//! * `new(correlation_header, completion)` — minimal spec.
33//! * `with_id(id, correlation_header, completion)` — explicit id.
34//! * `set_strategy(name)` / `set_store(name)` — chainable setters (return `self`).
35//! * `set_id(id)` — internal use (builder assigning auto-generated id).
36//! * Accessors: `id()`, `correlation_header()`, `completion()`, `strategy()`, `store()`.
37
38#[derive(Debug, Clone)]
39pub struct AggregatorSpec {
40    id: Option<String>,
41    correlation_header: String,
42    completion: String,
43    strategy: Option<String>,
44    store: Option<String>,
45}
46
47impl AggregatorSpec {
48    pub fn new<H: Into<String>, C: Into<String>>(correlation_header: H, completion: C) -> Self {
49        Self {
50            id: None,
51            correlation_header: correlation_header.into(),
52            completion: completion.into(),
53            strategy: None,
54            store: None,
55        }
56    }
57
58    pub fn with_id<I, H, C>(id: I, correlation_header: H, completion: C) -> Self
59    where
60        I: Into<String>,
61        H: Into<String>,
62        C: Into<String>,
63    {
64        Self {
65            id: Some(id.into()),
66            correlation_header: correlation_header.into(),
67            completion: completion.into(),
68            strategy: None,
69            store: None,
70        }
71    }
72
73    pub fn set_strategy<S: Into<String>>(mut self, strategy: S) -> Self {
74        self.strategy = Some(strategy.into());
75        self
76    }
77
78    pub fn set_store<S: Into<String>>(mut self, store: S) -> Self {
79        self.store = Some(store.into());
80        self
81    }
82
83    pub fn id(&self) -> Option<&str> {
84        self.id.as_deref()
85    }
86    pub fn correlation_header(&self) -> &str {
87        &self.correlation_header
88    }
89    pub fn completion(&self) -> &str {
90        &self.completion
91    }
92    pub fn strategy(&self) -> Option<&str> {
93        self.strategy.as_deref()
94    }
95    pub fn store(&self) -> Option<&str> {
96        self.store.as_deref()
97    }
98
99    /// Internal: builder assigns an auto-generated id.
100    pub fn set_id(&mut self, id: String) {
101        self.id = Some(id);
102    }
103}