frame_suite/
accumulators.rs

1// SPDX-License-Identifier: MPL-2.0
2//
3// Part of Auguth Labs open-source softwares.
4// Built for the Substrate framework.
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at https://mozilla.org/MPL/2.0/.
9//
10// Copyright (c) 2026 Auguth Labs (OPC) Pvt Ltd, India
11
12// ===============================================================================
13// `````````````````````````````` ACCUMULATORS SUITE `````````````````````````````
14// ===============================================================================
15
16//! Defines a generic interface for step-based progression systems.
17//!
18//! This abstraction models systems where a value is derived from
19//! internal state that is updated through discrete steps.
20
21// ===============================================================================
22// ``````````````````````````````````` IMPORTS ```````````````````````````````````
23// ===============================================================================
24
25use crate::base::{Countable, Delimited};
26
27// ===============================================================================
28// ````````````````````````````` DISCRETE ACCUMULATOR ````````````````````````````
29// ===============================================================================
30
31/// A trait for discrete accumulation with configurable step rules.
32///
33/// This trait models systems where progress happens in small, discrete steps,
34/// and those steps gradually accumulate into a larger meaningful value.
35///
36/// Instead of directly changing the final value every time, progress is first
37/// stored internally and only converted into a visible result when certain
38/// conditions (such as thresholds) are met.
39///
40/// ## Intuition
41///
42/// Think of this as a two-layer progression system:
43///
44/// 1. Small repeated actions add *internal progress*
45/// 2. Once enough progress is collected, the visible value increases
46///
47/// The internal progress is hidden, and `reveal` exposes only the final result.
48///
49/// ## Generic Roles of the Associated Types
50///
51/// * `Value`
52///   The final meaningful result exposed to consumers.
53///   This is what users care about (e.g., level, score, reputation).
54///
55/// * `Step`
56///   Represents one discrete unit of progress applied during each operation.
57///   Each increment or decrement applies one such step.
58///
59/// * `Accumulator`
60///   Internal state that tracks progress and any additional data needed
61///   to determine how the final value evolves over time.
62///
63/// * `Stepper`
64///   Defines the rules for how steps affect the accumulator.
65///   This may include configuration such as thresholds, scaling factors,
66///   or other logic governing accumulation behavior.
67///
68/// ## How Accumulation Works (Conceptually)
69///
70/// Forward progression:
71///
72/// ```text
73/// progress += step
74/// if progress reaches some condition (e.g., threshold):
75///     value increases
76///     progress is adjusted/reset accordingly
77/// ```
78///
79/// Reverse progression:
80///
81/// ```text
82/// progress -= step
83/// if progress would go below zero:
84///     value decreases
85///     progress is restored based on the rules
86/// ```
87///
88/// The exact logic is fully defined by the implementation.
89///
90/// ## Example Scenario (Conceptual)
91///
92/// Imagine a system where:
93/// - Each action adds a fixed amount of progress
94/// - A visible value increases only after enough progress is accumulated
95///
96/// Progress might evolve like this:
97///
98/// ```text
99/// Start: value = 0, internal progress = 0
100/// Step 1 -> internal progress increases
101/// Step 2 -> internal progress increases
102/// Step 3 -> internal progress reaches condition -> value becomes 1
103/// ```
104///
105/// Decrementing would reverse this process, potentially reducing the value
106/// and restoring some internal progress.
107///
108/// ## Design Flexibility
109///
110/// Implementors are free to define:
111/// - How internal progress is stored
112/// - What condition converts progress into value changes
113/// - How increments and decrements interact with that state
114/// - Any custom or domain-specific accumulation logic
115///
116/// This makes the trait suitable for a wide range of stepped progression systems
117/// such as reward meters, scoring engines, leveling mechanics, or quota trackers.
118pub trait DiscreteAccumulator {
119    /// The final value type that represents the accumulated result.
120    ///
121    /// This is the user-facing result derived from the internal accumulator state.
122    /// Implementations decide how internal progress maps to this value.
123    type Value: Countable;
124
125    /// The discrete unit of progress applied during accumulation operations.
126    ///
127    /// Each increment or decrement uses this unit to modify internal state.
128    type Step: Countable;
129
130    /// The internal state used to track accumulation progress.
131    ///
132    /// This may contain any data required to determine how the final value evolves,
133    /// including partial progress toward future value changes.
134    type Accumulator: Delimited;
135
136    /// Configuration describing how steps affect the accumulator.
137    ///
138    /// This governs the rules of accumulation, such as when progress should
139    /// convert into value changes or how reverse progression behaves.
140    type Stepper: Delimited;
141
142    /// Applies forward progression to the accumulator.
143    ///
144    /// This operation increases internal progress according to the rules defined
145    /// by the `Stepper`. Depending on the implementation, this may cause the
146    /// revealed value to increase once certain conditions are met.
147    fn increment(accum: &mut Self::Accumulator, stepper: &Self::Stepper);
148
149    /// Applies reverse progression to the accumulator.
150    ///
151    /// This operation removes internal progress. If reversing progress crosses
152    /// important boundaries (such as previously completed thresholds), the
153    /// revealed value may decrease and internal progress may be restored
154    /// accordingly.
155    fn decrement(accum: &mut Self::Accumulator, stepper: &Self::Stepper);
156
157    /// Reveals the current accumulated value derived from the internal state.
158    ///
159    /// This provides read-only access to the meaningful result while hiding
160    /// the internal progress details used to compute it.
161    fn reveal(accum: &Self::Accumulator) -> Self::Value;
162}