1use chrono::{DateTime, Utc};
6
7#[derive(Debug, Clone, PartialEq, Default)]
9#[non_exhaustive]
10pub enum ReplayAction {
11 #[default]
13 None,
14
15 Play,
18 Pause,
20 TogglePlayPause,
22 Stop,
24 Reset,
26
27 StepForward,
30 StepBackward,
32 StepForwardN(usize),
34 StepBackwardN(usize),
36 JumpToBar(usize),
38 JumpToDate(DateTime<Utc>),
40 JumpToStart,
42 JumpToEnd,
44 JumpToPercent(f32),
46
47 SetSpeed(f32),
50 SpeedUp,
52 SlowDown,
54
55 EnterReplayMode,
58 ExitReplayMode,
60 ToggleReplayMode,
62
63 LoadData {
66 symbol: String,
68 start: Option<DateTime<Utc>>,
70 end: Option<DateTime<Utc>>,
72 },
73 UnloadData,
75
76 SetStartDate(DateTime<Utc>),
79 SetEndDate(DateTime<Utc>),
81 SetDateRange {
83 start: DateTime<Utc>,
85 end: DateTime<Utc>,
87 },
88
89 AddMarker {
92 label: Option<String>,
94 color: Option<[u8; 4]>,
96 },
97 RemoveMarker(usize),
99 ClearMarkers,
101}
102
103impl ReplayAction {
104 pub fn affects_playback(&self) -> bool {
106 matches!(
107 self,
108 ReplayAction::Play
109 | ReplayAction::Pause
110 | ReplayAction::TogglePlayPause
111 | ReplayAction::Stop
112 | ReplayAction::SetSpeed(_)
113 | ReplayAction::SpeedUp
114 | ReplayAction::SlowDown
115 )
116 }
117
118 pub fn affects_pos(&self) -> bool {
120 matches!(
121 self,
122 ReplayAction::StepForward
123 | ReplayAction::StepBackward
124 | ReplayAction::StepForwardN(_)
125 | ReplayAction::StepBackwardN(_)
126 | ReplayAction::JumpToBar(_)
127 | ReplayAction::JumpToDate(_)
128 | ReplayAction::JumpToStart
129 | ReplayAction::JumpToEnd
130 | ReplayAction::JumpToPercent(_)
131 )
132 }
133
134 pub fn affects_mode(&self) -> bool {
136 matches!(
137 self,
138 ReplayAction::EnterReplayMode
139 | ReplayAction::ExitReplayMode
140 | ReplayAction::ToggleReplayMode
141 )
142 }
143}
144
145#[derive(Debug, Clone, Copy, PartialEq, Default)]
147pub enum ReplaySpeed {
148 Slowest,
150 Slower,
152 Slow,
154 #[default]
156 Normal,
157 Fast,
159 Faster,
161 VeryFast,
163 Fastest,
165 Turbo,
167 Max,
169 Custom(f32),
171}
172
173impl ReplaySpeed {
174 pub fn multiplier(&self) -> f32 {
177 match self {
178 ReplaySpeed::Slowest => 0.1,
179 ReplaySpeed::Slower => 0.25,
180 ReplaySpeed::Slow => 0.5,
181 ReplaySpeed::Normal => 1.0,
182 ReplaySpeed::Fast => 2.0,
183 ReplaySpeed::Faster => 5.0,
184 ReplaySpeed::VeryFast => 10.0,
185 ReplaySpeed::Fastest => 25.0,
186 ReplaySpeed::Turbo => 50.0,
187 ReplaySpeed::Max => 100.0,
188 ReplaySpeed::Custom(v) if v.is_finite() => v.clamp(0.1, 100.0),
189 ReplaySpeed::Custom(_) => 1.0,
190 }
191 }
192
193 pub fn faster(&self) -> Self {
195 match self {
196 ReplaySpeed::Slowest => ReplaySpeed::Slower,
197 ReplaySpeed::Slower => ReplaySpeed::Slow,
198 ReplaySpeed::Slow => ReplaySpeed::Normal,
199 ReplaySpeed::Normal => ReplaySpeed::Fast,
200 ReplaySpeed::Fast => ReplaySpeed::Faster,
201 ReplaySpeed::Faster => ReplaySpeed::VeryFast,
202 ReplaySpeed::VeryFast => ReplaySpeed::Fastest,
203 ReplaySpeed::Fastest => ReplaySpeed::Turbo,
204 ReplaySpeed::Turbo | ReplaySpeed::Max => ReplaySpeed::Max,
205 ReplaySpeed::Custom(_) => ReplaySpeed::Custom((self.multiplier() * 2.0).min(100.0)),
206 }
207 }
208
209 pub fn slower(&self) -> Self {
211 match self {
212 ReplaySpeed::Max => ReplaySpeed::Turbo,
213 ReplaySpeed::Turbo => ReplaySpeed::Fastest,
214 ReplaySpeed::Fastest => ReplaySpeed::VeryFast,
215 ReplaySpeed::VeryFast => ReplaySpeed::Faster,
216 ReplaySpeed::Faster => ReplaySpeed::Fast,
217 ReplaySpeed::Fast => ReplaySpeed::Normal,
218 ReplaySpeed::Normal => ReplaySpeed::Slow,
219 ReplaySpeed::Slow => ReplaySpeed::Slower,
220 ReplaySpeed::Slower | ReplaySpeed::Slowest => ReplaySpeed::Slowest,
221 ReplaySpeed::Custom(_) => ReplaySpeed::Custom((self.multiplier() / 2.0).max(0.1)),
222 }
223 }
224
225 pub fn label(&self) -> String {
227 format!("{:.1}x", self.multiplier())
228 }
229
230 pub fn presets() -> &'static [ReplaySpeed] {
232 &[
233 ReplaySpeed::Slowest,
234 ReplaySpeed::Slower,
235 ReplaySpeed::Slow,
236 ReplaySpeed::Normal,
237 ReplaySpeed::Fast,
238 ReplaySpeed::Faster,
239 ReplaySpeed::VeryFast,
240 ReplaySpeed::Fastest,
241 ReplaySpeed::Turbo,
242 ReplaySpeed::Max,
243 ]
244 }
245}
246
247impl From<f32> for ReplaySpeed {
248 fn from(value: f32) -> Self {
249 let value = ReplaySpeed::Custom(value).multiplier();
250 for preset in Self::presets() {
252 if (preset.multiplier() - value).abs() < 0.01 {
253 return *preset;
254 }
255 }
256 ReplaySpeed::Custom(value)
257 }
258}