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}