livesplit_core/run/
run_metadata.rs

1use crate::{
2    platform::prelude::*,
3    util::{
4        ordered_map::{Iter, Map},
5        PopulateString,
6    },
7};
8use serde::{Deserialize, Serialize};
9
10/// A custom variable is a key value pair storing additional information about a
11/// run. Unlike the speedrun.com variables, these can be fully custom and don't
12/// need to correspond to anything on speedrun.com. Permanent custom variables
13/// can be specified by the runner. Additionally auto splitters or other sources
14/// may provide temporary custom variables that are not stored in the splits
15/// files.
16#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
17pub struct CustomVariable {
18    /// The current value of the custom variable. This may be provided by the
19    /// runner in the run editor or it may be provided through other means such
20    /// as an auto splitter.
21    pub value: String,
22    /// States whether the variable is permanent. Temporary variables don't get
23    /// stored in splits files. They also don't get shown in the run editor.
24    pub is_permanent: bool,
25}
26
27impl CustomVariable {
28    /// Turns the custom variable into a permanent one. If it already is
29    /// permanent variable, nothing happens.
30    pub fn permanent(&mut self) -> &mut Self {
31        self.is_permanent = true;
32        self
33    }
34
35    /// Sets the value of the custom variable.
36    pub fn set_value<S>(&mut self, value: S)
37    where
38        S: PopulateString,
39    {
40        value.populate(&mut self.value);
41    }
42
43    /// Clears the value of the custom variable. This does not delete the custom
44    /// variable.
45    pub fn clear_value(&mut self) {
46        self.value.clear();
47    }
48}
49
50/// The `RunMetadata` struct stores optional information about a run, like the
51/// platform and region of the game.
52#[derive(Default, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
53pub struct RunMetadata {
54    /// The speedrun.com Run ID of the run. You need to ensure that the record
55    /// on speedrun.com matches up with the Personal Best of this run. This may
56    /// be empty if there's no association.
57    pub run_id: String,
58    /// The name of the platform this game is run on. This may be empty if it's
59    /// not specified.
60    pub platform_name: String,
61    /// Specifies whether this speedrun is done on an emulator. Keep in mind
62    /// that `false` may also mean that this information is simply not known.
63    pub uses_emulator: bool,
64    /// The name of the region this game is from. This may be empty if it's not
65    /// specified.
66    pub region_name: String,
67    /// Stores all the speedrun.com variables. A speedrun.com variable is a key
68    /// value pair storing additional information about the category. An example
69    /// of this may be whether Amiibos are used in this category. Use a custom
70    /// variable for storing arbitrary key value pairs that are independent of
71    /// speedrun.com.
72    pub speedrun_com_variables: Map<String>,
73    /// Stores all the custom variables. A custom variable is a key value pair
74    /// storing additional information about a run. Unlike the speedrun.com
75    /// variables, these can be fully custom and don't need to correspond to
76    /// anything on speedrun.com. Permanent custom variables can be specified by
77    /// the runner. Additionally auto splitters or other sources may provide
78    /// temporary custom variables that are not stored in the splits files.
79    pub custom_variables: Map<CustomVariable>,
80}
81
82impl RunMetadata {
83    /// Creates a new empty Run Metadata.
84    #[inline]
85    pub fn new() -> Self {
86        Default::default()
87    }
88
89    /// Accesses the speedrun.com Run ID of the run. This Run ID specify which
90    /// Record on speedrun.com this run is associated with. This should be
91    /// changed once the Personal Best doesn't match up with that record
92    /// anymore. This may be empty if there's no association.
93    #[inline]
94    pub fn run_id(&self) -> &str {
95        &self.run_id
96    }
97
98    /// Sets the speedrun.com Run ID of the run. You need to ensure that the
99    /// record on speedrun.com matches up with the Personal Best of this run.
100    /// This may be empty if there's no association.
101    #[inline]
102    pub fn set_run_id<S>(&mut self, id: S)
103    where
104        S: PopulateString,
105    {
106        id.populate(&mut self.run_id);
107    }
108
109    /// Accesses the name of the platform this game is run on. This may be empty
110    /// if it's not specified.
111    #[inline]
112    pub fn platform_name(&self) -> &str {
113        &self.platform_name
114    }
115
116    /// Sets the name of the platform this game is run on. This may be empty if
117    /// it's not specified.
118    #[inline]
119    pub fn set_platform_name<S>(&mut self, name: S)
120    where
121        S: PopulateString,
122    {
123        name.populate(&mut self.platform_name);
124    }
125
126    /// Returns `true` if this speedrun is done on an emulator. However `false`
127    /// may also indicate that this information is simply not known.
128    #[inline]
129    pub const fn uses_emulator(&self) -> bool {
130        self.uses_emulator
131    }
132
133    /// Specifies whether this speedrun is done on an emulator. Keep in mind
134    /// that `false` may also mean that this information is simply not known.
135    #[inline]
136    pub fn set_emulator_usage(&mut self, uses_emulator: bool) {
137        self.uses_emulator = uses_emulator;
138    }
139
140    /// Accesses the name of the region this game is from. This may be empty if
141    /// it's not specified.
142    #[inline]
143    pub fn region_name(&self) -> &str {
144        &self.region_name
145    }
146
147    /// Sets the name of the region this game is from. This may be empty if it's
148    /// not specified.
149    #[inline]
150    pub fn set_region_name<S>(&mut self, region_name: S)
151    where
152        S: PopulateString,
153    {
154        region_name.populate(&mut self.region_name);
155    }
156
157    /// Sets the speedrun.com variable with the name specified to the value
158    /// specified. A speedrun.com variable is an arbitrary key value pair
159    /// storing additional information about the category. An example of this
160    /// may be whether Amiibos are used in this category. If the variable
161    /// doesn't exist yet, it is being inserted.
162    pub fn set_speedrun_com_variable<N, V>(&mut self, name: N, value: V)
163    where
164        N: PopulateString,
165        V: PopulateString,
166    {
167        let entry = self.speedrun_com_variables.entry(name).or_default();
168        value.populate(entry);
169    }
170
171    /// Removes the speedrun.com variable with the name specified.
172    pub fn remove_speedrun_com_variable(&mut self, name: &str) {
173        self.speedrun_com_variables.shift_remove(name);
174    }
175
176    /// Returns an iterator iterating over all the speedrun.com variables and
177    /// their values that have been specified.
178    pub fn speedrun_com_variables(&self) -> Iter<'_, String> {
179        self.speedrun_com_variables.iter()
180    }
181
182    /// Accesses the custom variable with the name specified if there is one.
183    pub fn custom_variable(&self, name: &str) -> Option<&CustomVariable> {
184        self.custom_variables.get(name)
185    }
186
187    /// Accesses the value of the custom variable with the name specified if
188    /// there is one.
189    pub fn custom_variable_value(&self, name: &str) -> Option<&str> {
190        Some(&self.custom_variable(name)?.value)
191    }
192
193    /// Mutably accesses the custom variable with the name specified. If the
194    /// variable does not exist, it gets created as a temporary variable.
195    pub fn custom_variable_mut<S>(&mut self, name: S) -> &mut CustomVariable
196    where
197        S: PopulateString,
198    {
199        self.custom_variables.entry(name).or_default()
200    }
201
202    /// Removes the custom variable with the name specified. Nothing happens if
203    /// the variable does not exist.
204    pub fn remove_custom_variable(&mut self, name: &str) {
205        self.custom_variables.shift_remove(name);
206    }
207
208    /// Returns an iterator iterating over all the custom variables and their
209    /// values. This includes both temporary and permanent variables.
210    pub fn custom_variables(&self) -> Iter<'_, CustomVariable> {
211        self.custom_variables.iter()
212    }
213
214    /// Resets all the Metadata Information.
215    pub fn clear(&mut self) {
216        self.run_id.clear();
217        self.platform_name.clear();
218        self.region_name.clear();
219        self.uses_emulator = false;
220        self.speedrun_com_variables.clear();
221        self.custom_variables.clear();
222    }
223}