konnektoren_core/achievements/
achievement_statistic.rs1use 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}