Skip to content

Commit ce8ce79

Browse files
unhappychoiceclaude
andcommitted
feat: add challenge_path to StageResult for proper stage name display
- Add challenge_path field to StageResult model - Update field names for clarity (valid_keystrokes, valid_mistakes) - Improve SessionResult with better field semantics 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 42adc73 commit ce8ce79

File tree

2 files changed

+58
-39
lines changed

2 files changed

+58
-39
lines changed

src/models/session.rs

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::stage::{Stage, StageResult};
2-
use crate::scoring::ScoringEngine;
2+
use crate::scoring::StageTracker;
33
use std::time::{Duration, Instant};
44

55
#[derive(Debug, Clone)]
@@ -11,27 +11,26 @@ pub struct Session {
1111
#[derive(Debug, Clone)]
1212
pub struct SessionResult {
1313
pub session_start_time: Instant,
14-
pub session_duration: Duration,
15-
pub total_session_time: Duration, // Alias for session_duration for backward compatibility
14+
pub session_duration: Duration, // Total duration (valid + invalid) for backward compatibility
15+
pub valid_session_duration: Duration, // Duration of completed stages only
16+
pub invalid_session_duration: Duration, // Duration of skipped/failed stages
1617
pub stages_completed: usize,
1718
pub stages_attempted: usize,
1819
pub stages_skipped: usize,
19-
pub total_challenges_completed: usize, // Alias for stages_completed
20-
pub total_challenges_attempted: usize, // Alias for stages_attempted
21-
pub total_skips_used: usize, // Alias for stages_skipped
2220
pub stage_results: Vec<StageResult>,
2321
pub overall_accuracy: f64,
2422
pub overall_wpm: f64,
2523
pub overall_cpm: f64,
26-
pub total_keystrokes: usize,
27-
pub total_mistakes: usize,
28-
pub total_partial_effort_keystrokes: usize,
29-
pub total_partial_effort_mistakes: usize,
24+
pub valid_keystrokes: usize,
25+
pub valid_mistakes: usize,
26+
pub invalid_keystrokes: usize,
27+
pub invalid_mistakes: usize,
3028
pub best_stage_wpm: f64,
3129
pub worst_stage_wpm: f64,
3230
pub best_stage_accuracy: f64,
3331
pub worst_stage_accuracy: f64,
3432
pub session_score: f64,
33+
pub session_successful: bool, // True if session was completed successfully
3534
}
3635

3736
impl Session {
@@ -48,39 +47,37 @@ impl SessionResult {
4847
Self {
4948
session_start_time: Instant::now(),
5049
session_duration: Duration::default(),
51-
total_session_time: Duration::default(),
50+
valid_session_duration: Duration::default(),
51+
invalid_session_duration: Duration::default(),
5252
stages_completed: 0,
5353
stages_attempted: 0,
5454
stages_skipped: 0,
55-
total_challenges_completed: 0,
56-
total_challenges_attempted: 0,
57-
total_skips_used: 0,
5855
stage_results: Vec::new(),
5956
overall_accuracy: 0.0,
6057
overall_wpm: 0.0,
6158
overall_cpm: 0.0,
62-
total_keystrokes: 0,
63-
total_mistakes: 0,
64-
total_partial_effort_keystrokes: 0,
65-
total_partial_effort_mistakes: 0,
59+
valid_keystrokes: 0,
60+
valid_mistakes: 0,
61+
invalid_keystrokes: 0,
62+
invalid_mistakes: 0,
6663
best_stage_wpm: 0.0,
6764
worst_stage_wpm: f64::MAX,
6865
best_stage_accuracy: 0.0,
6966
worst_stage_accuracy: f64::MAX,
7067
session_score: 0.0,
68+
session_successful: false,
7169
}
7270
}
7371

7472
pub fn add_stage_result(
7573
&mut self,
7674
_stage_name: String,
7775
stage_result: StageResult,
78-
engine: &ScoringEngine,
76+
engine: &StageTracker,
7977
) {
80-
self.total_challenges_completed += 1;
81-
self.stages_completed = self.total_challenges_completed;
82-
self.total_keystrokes += engine.total_chars();
83-
self.total_mistakes += stage_result.mistakes;
78+
self.stages_completed += 1;
79+
self.valid_keystrokes += engine.get_data().keystrokes.len();
80+
self.valid_mistakes += stage_result.mistakes;
8481
self.session_score += stage_result.challenge_score;
8582

8683
// Track best/worst performance
@@ -99,40 +96,36 @@ impl SessionResult {
9996
}
10097

10198
pub fn add_skip(&mut self) {
102-
self.total_skips_used += 1;
103-
self.stages_skipped = self.total_skips_used;
104-
self.total_challenges_attempted += 1;
105-
self.stages_attempted = self.total_challenges_attempted;
99+
self.stages_skipped += 1;
100+
self.stages_attempted += 1;
106101
}
107102

108103
pub fn add_partial_effort(&mut self, keystrokes: usize, mistakes: usize) {
109-
self.total_partial_effort_keystrokes += keystrokes;
110-
self.total_partial_effort_mistakes += mistakes;
104+
self.invalid_keystrokes += keystrokes;
105+
self.invalid_mistakes += mistakes;
111106
}
112107

113108
// Calculate total effort including both completed and partial
114109
pub fn total_effort_keystrokes(&self) -> usize {
115-
self.total_keystrokes + self.total_partial_effort_keystrokes
110+
self.valid_keystrokes + self.invalid_keystrokes
116111
}
117112

118113
pub fn total_effort_mistakes(&self) -> usize {
119-
self.total_mistakes + self.total_partial_effort_mistakes
114+
self.valid_mistakes + self.invalid_mistakes
120115
}
121116

122117
pub fn finalize_session(&mut self) {
123118
self.session_duration = self.session_start_time.elapsed();
124-
self.total_session_time = self.session_duration;
125-
self.total_challenges_attempted = self.total_challenges_completed + self.total_skips_used;
126-
self.stages_attempted = self.total_challenges_attempted;
119+
self.stages_attempted = self.stages_completed + self.stages_skipped;
127120

128121
// Calculate overall metrics
129-
if self.session_duration.as_secs() > 0 && self.total_keystrokes > 0 {
122+
if self.session_duration.as_secs() > 0 && self.valid_keystrokes > 0 {
130123
self.overall_cpm =
131-
(self.total_keystrokes as f64 / self.session_duration.as_secs_f64()) * 60.0;
124+
(self.valid_keystrokes as f64 / self.session_duration.as_secs_f64()) * 60.0;
132125
self.overall_wpm = self.overall_cpm / 5.0;
133-
self.overall_accuracy = ((self.total_keystrokes.saturating_sub(self.total_mistakes))
126+
self.overall_accuracy = ((self.valid_keystrokes.saturating_sub(self.valid_mistakes))
134127
as f64
135-
/ self.total_keystrokes as f64)
128+
/ self.valid_keystrokes as f64)
136129
* 100.0;
137130
}
138131

@@ -146,7 +139,7 @@ impl SessionResult {
146139
}
147140

148141
pub fn get_session_completion_status(&self) -> String {
149-
match (self.total_challenges_completed, self.total_skips_used) {
142+
match (self.stages_completed, self.stages_skipped) {
150143
(0, 0) => "No challenges attempted".to_string(),
151144
(completed, 0) if completed > 0 => {
152145
format!("Perfect session! {} challenges completed", completed)

src/models/stage.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub struct StageResult {
1212
pub cpm: f64,
1313
pub wpm: f64,
1414
pub accuracy: f64,
15+
pub keystrokes: usize,
1516
pub mistakes: usize,
1617
pub consistency_streaks: Vec<usize>,
1718
pub completion_time: Duration,
@@ -24,6 +25,31 @@ pub struct StageResult {
2425
pub overall_total: usize,
2526
pub was_skipped: bool,
2627
pub was_failed: bool,
28+
pub challenge_path: String,
29+
}
30+
31+
impl Default for StageResult {
32+
fn default() -> Self {
33+
Self {
34+
cpm: 0.0,
35+
wpm: 0.0,
36+
accuracy: 0.0,
37+
keystrokes: 0,
38+
mistakes: 0,
39+
consistency_streaks: vec![],
40+
completion_time: Duration::new(0, 0),
41+
challenge_score: 0.0,
42+
rank_name: "Unranked".to_string(),
43+
tier_name: "Beginner".to_string(),
44+
tier_position: 0,
45+
tier_total: 0,
46+
overall_position: 0,
47+
overall_total: 0,
48+
was_skipped: false,
49+
was_failed: false,
50+
challenge_path: String::new(),
51+
}
52+
}
2753
}
2854

2955
impl Stage {

0 commit comments

Comments
 (0)