konnektoren_core/achievements/
achievement_statistic.rs

1use crate::prelude::Metric;
2
3pub trait AchievementStatistic: Metric {}
4
5pub trait TotalChallenges: AchievementStatistic {
6    fn name(&self) -> &str {
7        "total_challenges"
8    }
9    fn description(&self) -> &str {
10        "Total number of challenges completed"
11    }
12
13    fn total_challenges(&self) -> u32;
14    fn value(&self) -> f64 {
15        self.total_challenges() as f64
16    }
17}
18
19pub trait AveragePerformance: AchievementStatistic {
20    fn name(&self) -> &str {
21        "average_performance"
22    }
23    fn description(&self) -> &str {
24        "Average performance across all challenges"
25    }
26    fn average_performance(&self) -> f64;
27    fn value(&self) -> f64 {
28        self.average_performance()
29    }
30}
31
32pub trait TotalXp: AchievementStatistic {
33    fn name(&self) -> &str {
34        "total_xp"
35    }
36    fn description(&self) -> &str {
37        "Total experience points earned"
38    }
39    fn total_xp(&self) -> u32;
40    fn value(&self) -> f64 {
41        self.total_xp() as f64
42    }
43}
44
45pub trait CompletedGamePaths: AchievementStatistic {
46    fn name(&self) -> &str {
47        "completed_game_paths"
48    }
49    fn description(&self) -> &str {
50        "Number of game paths completed"
51    }
52    fn completed_game_paths(&self) -> u32;
53    fn value(&self) -> f64 {
54        self.completed_game_paths() as f64
55    }
56}
57
58pub trait PerfectChallenges: AchievementStatistic {
59    fn name(&self) -> &str {
60        "perfect_challenges"
61    }
62    fn description(&self) -> &str {
63        "Number of perfect challenges completed"
64    }
65    fn perfect_challenges(&self) -> u32;
66    fn value(&self) -> f64 {
67        self.perfect_challenges() as f64
68    }
69}
70
71pub trait DifferentChallengeTypesCompleted: AchievementStatistic {
72    fn name(&self) -> &str {
73        "different_challenge_types_completed"
74    }
75    fn description(&self) -> &str {
76        "Number of different challenge types completed"
77    }
78    fn different_challenge_types_completed(&self) -> u32;
79    fn value(&self) -> f64 {
80        self.different_challenge_types_completed() as f64
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87    use crate::prelude::Metric;
88
89    struct DummyStats;
90
91    impl Metric for DummyStats {
92        fn name(&self) -> &str {
93            "dummy"
94        }
95        fn value(&self) -> f64 {
96            0.0
97        }
98        fn description(&self) -> &str {
99            "dummy metric"
100        }
101    }
102
103    impl AchievementStatistic for DummyStats {}
104
105    impl TotalChallenges for DummyStats {
106        fn total_challenges(&self) -> u32 {
107            42
108        }
109    }
110    impl AveragePerformance for DummyStats {
111        fn average_performance(&self) -> f64 {
112            88.5
113        }
114    }
115    impl TotalXp for DummyStats {
116        fn total_xp(&self) -> u32 {
117            1234
118        }
119    }
120    impl CompletedGamePaths for DummyStats {
121        fn completed_game_paths(&self) -> u32 {
122            3
123        }
124    }
125    impl PerfectChallenges for DummyStats {
126        fn perfect_challenges(&self) -> u32 {
127            7
128        }
129    }
130    impl DifferentChallengeTypesCompleted for DummyStats {
131        fn different_challenge_types_completed(&self) -> u32 {
132            5
133        }
134    }
135
136    #[test]
137    fn test_total_challenges_trait() {
138        let stats = DummyStats;
139        assert_eq!(TotalChallenges::name(&stats), "total_challenges");
140        assert_eq!(
141            TotalChallenges::description(&stats),
142            "Total number of challenges completed"
143        );
144        assert_eq!(stats.total_challenges(), 42);
145        assert_eq!(TotalChallenges::value(&stats), 42.0);
146    }
147
148    #[test]
149    fn test_average_performance_trait() {
150        let stats = DummyStats;
151        assert_eq!(AveragePerformance::name(&stats), "average_performance");
152        assert_eq!(
153            AveragePerformance::description(&stats),
154            "Average performance across all challenges"
155        );
156        assert_eq!(stats.average_performance(), 88.5);
157        assert_eq!(AveragePerformance::value(&stats), 88.5);
158    }
159
160    #[test]
161    fn test_total_xp_trait() {
162        let stats = DummyStats;
163        assert_eq!(TotalXp::name(&stats), "total_xp");
164        assert_eq!(
165            TotalXp::description(&stats),
166            "Total experience points earned"
167        );
168        assert_eq!(stats.total_xp(), 1234);
169        assert_eq!(TotalXp::value(&stats), 1234.0);
170    }
171
172    #[test]
173    fn test_completed_game_paths_trait() {
174        let stats = DummyStats;
175        assert_eq!(CompletedGamePaths::name(&stats), "completed_game_paths");
176        assert_eq!(
177            CompletedGamePaths::description(&stats),
178            "Number of game paths completed"
179        );
180        assert_eq!(stats.completed_game_paths(), 3);
181        assert_eq!(CompletedGamePaths::value(&stats), 3.0);
182    }
183
184    #[test]
185    fn test_perfect_challenges_trait() {
186        let stats = DummyStats;
187        assert_eq!(PerfectChallenges::name(&stats), "perfect_challenges");
188        assert_eq!(
189            PerfectChallenges::description(&stats),
190            "Number of perfect challenges completed"
191        );
192        assert_eq!(stats.perfect_challenges(), 7);
193        assert_eq!(PerfectChallenges::value(&stats), 7.0);
194    }
195
196    #[test]
197    fn test_different_challenge_types_completed_trait() {
198        let stats = DummyStats;
199        assert_eq!(
200            DifferentChallengeTypesCompleted::name(&stats),
201            "different_challenge_types_completed"
202        );
203        assert_eq!(
204            DifferentChallengeTypesCompleted::description(&stats),
205            "Number of different challenge types completed"
206        );
207        assert_eq!(stats.different_challenge_types_completed(), 5);
208        assert_eq!(DifferentChallengeTypesCompleted::value(&stats), 5.0);
209    }
210}