rust_rocket/
player.rs

1//! Player code for playing previously saved tracks, [`RocketPlayer`].
2
3use crate::{track::Track, Tracks};
4use std::collections::HashMap;
5
6/// A player for tracks from
7/// [`RocketClient::save_tracks`](crate::RocketClient::save_tracks).
8///
9/// # Usage
10///
11/// See [module-level documentation](crate::player#Usage).
12///
13/// # Examples
14///
15/// ```rust,no_run
16/// # use rust_rocket::{RocketPlayer, Tracks};
17/// # use std::fs::File;
18/// // Run the demo and edit your sync tracks (see top level documentation),
19/// // then call save_tracks and serialize tracks to a file (see save_tracks documentation)
20///
21/// // And deserialize from a file in your release build
22/// let mut file = File::open("tracks.bin").expect("Failed to open tracks.bin");
23/// # #[cfg(feature = "bincode")]
24/// # {
25/// let tracks = bincode::decode_from_std_read(&mut file, bincode::config::standard())
26///     .expect("Failed to decode tracks.bin");
27/// let player = RocketPlayer::new(tracks);
28/// println!("Value at row 123: {}", player.get_track("test").unwrap().get_value(123.));
29/// # }
30/// # Ok::<(), rust_rocket::client::Error>(())
31/// ```
32pub struct RocketPlayer {
33    tracks: HashMap<Box<str>, Track>,
34}
35
36impl RocketPlayer {
37    /// Constructs a `RocketPlayer` from `Track`s.
38    pub fn new(tracks: Tracks) -> Self {
39        // Convert to a HashMap for perf (not benchmarked)
40        let tracks: HashMap<Box<str>, Track> = tracks
41            .into_iter()
42            .map(|track| (String::from(track.get_name()).into_boxed_str(), track))
43            .collect();
44
45        Self { tracks }
46    }
47
48    /// Get track by name.
49    pub fn get_track(&self, name: &str) -> Option<&Track> {
50        self.tracks.get(name)
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57    use crate::interpolation::Interpolation;
58    use crate::track::Key;
59
60    fn get_test_tracks() -> Tracks {
61        vec![
62            {
63                let mut track = Track::new("test1");
64                track.set_key(Key::new(0, 1.0, Interpolation::Step));
65                track.set_key(Key::new(5, 0.0, Interpolation::Step));
66                track.set_key(Key::new(10, 1.0, Interpolation::Step));
67                track
68            },
69            {
70                let mut track = Track::new("test2");
71                track.set_key(Key::new(0, 2.0, Interpolation::Step));
72                track.set_key(Key::new(5, 0.0, Interpolation::Step));
73                track.set_key(Key::new(10, 2.0, Interpolation::Step));
74                track
75            },
76        ]
77    }
78
79    #[test]
80    fn finds_all_tracks() {
81        let tracks = get_test_tracks();
82        let player = RocketPlayer::new(tracks);
83
84        // Ugly repeated calls to get_track to reflect average use case :)
85
86        assert_eq!(player.get_track("test1").unwrap().get_value(0.), 1.0);
87        assert_eq!(player.get_track("test2").unwrap().get_value(0.), 2.0);
88    }
89
90    #[test]
91    fn no_surprise_tracks() {
92        let tracks = get_test_tracks();
93        let player = RocketPlayer::new(tracks);
94        assert!(player
95            .get_track("hello this track should not exist")
96            .is_none());
97    }
98}