1#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct FoldOutcome<S> {
8 pub state: S,
10
11 pub entries_processed: usize,
13}
14
15impl<S> FoldOutcome<S> {
16 pub fn new(state: S, entries_processed: usize) -> Self {
18 Self {
19 state,
20 entries_processed,
21 }
22 }
23
24 pub fn map<T, F: FnOnce(S) -> T>(self, f: F) -> FoldOutcome<T> {
26 FoldOutcome::new(f(self.state), self.entries_processed)
27 }
28}
29
30impl<S: Default> Default for FoldOutcome<S> {
31 fn default() -> Self {
32 Self::new(S::default(), 0)
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn test_fold_outcome_creation() {
42 let result = FoldOutcome::new(42, 10);
43 assert_eq!(result.state, 42);
44 assert_eq!(result.entries_processed, 10);
45 }
46
47 #[test]
48 fn test_fold_outcome_map() {
49 let result = FoldOutcome::new(42, 10);
50 let mapped = result.map(|x| x.to_string());
51 assert_eq!(mapped.state, "42");
52 assert_eq!(mapped.entries_processed, 10);
53 }
54
55 #[test]
56 fn deterministic_no_timing_fields() {
57 let a = FoldOutcome::new(7usize, 3);
58 let b = FoldOutcome::new(7usize, 3);
59 assert_eq!(a, b);
60 }
61
62 #[test]
63 fn default_is_zero_state_zero_count() {
64 let d = FoldOutcome::<usize>::default();
65 assert_eq!(d.state, 0);
66 assert_eq!(d.entries_processed, 0);
67 }
68}