arma_rs/value/loadout/
magazine.rs

1use crate::{FromArma, FromArmaError, IntoArma, Value};
2
3#[derive(Debug, Default, Clone, PartialEq, Eq)]
4/// A magazine loaded into a weapon
5pub struct Magazine(Option<(String, u32)>);
6impl Magazine {
7    /// Create a new magazine
8    #[must_use]
9    pub const fn new(class: String, count: u32) -> Self {
10        Self(Some((class, count)))
11    }
12
13    /// The magazine exists
14    #[must_use]
15    pub const fn exists(&self) -> bool {
16        self.0.is_some()
17    }
18
19    /// Arma class name of the magazine
20    #[must_use]
21    pub fn class(&self) -> Option<&str> {
22        self.0.as_ref().map(|(c, _)| c.as_str())
23    }
24
25    /// Set the class name of the magazine
26    pub fn set_class(&mut self, class: &str) {
27        if let Some(magazine) = self.0.as_mut() {
28            magazine.0 = class.to_string();
29        } else {
30            self.0 = Some((class.to_string(), 0));
31        }
32    }
33
34    /// The remaining ammo in the magazine
35    #[must_use]
36    pub fn ammo(&self) -> Option<u32> {
37        self.0.as_ref().map(|(_, a)| a.to_owned())
38    }
39
40    /// Set the remaining ammo in the magazine
41    /// Returns true if the ammo was set, false if the magazine was not initialized
42    pub fn set_ammo(&mut self, ammo: u32) -> bool {
43        if let Some(magazine) = self.0.as_mut() {
44            magazine.1 = ammo;
45            true
46        } else {
47            false
48        }
49    }
50}
51impl FromArma for Magazine {
52    fn from_arma(s: String) -> Result<Self, FromArmaError> {
53        if s == "[]" {
54            return Ok(Self(None));
55        }
56        <(String, u32)>::from_arma(s).map(|(name, count)| Self(Some((name, count))))
57    }
58}
59impl IntoArma for Magazine {
60    fn to_arma(&self) -> Value {
61        self.0.as_ref().map_or_else(
62            || Value::Array(vec![]),
63            |magazine| {
64                Value::Array(vec![
65                    Value::String(magazine.0.clone()),
66                    Value::Number(f64::from(magazine.1)),
67                ])
68            },
69        )
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::Magazine;
76    use crate::{FromArma, IntoArma, Value};
77
78    #[test]
79    fn test_magazine() {
80        let mut magazine = Magazine::new("ACE_M84".to_string(), 10);
81        assert!(magazine.exists());
82        assert_eq!(magazine.class(), Some("ACE_M84"));
83        assert_eq!(magazine.ammo(), Some(10));
84        magazine.set_class("ACE_M84_HEDP");
85        assert_eq!(magazine.class(), Some("ACE_M84_HEDP"));
86        magazine.set_ammo(20);
87        assert_eq!(magazine.ammo(), Some(20));
88    }
89
90    #[test]
91    fn exists() {
92        let magazine = Magazine::default();
93        assert!(!magazine.exists());
94        let magazine = Magazine::new("ACE_M84".to_string(), 10);
95        assert!(magazine.exists());
96    }
97
98    #[test]
99    fn class() {
100        let mut magazine = Magazine::new("ACE_M84".to_string(), 10);
101        assert_eq!(magazine.class(), Some("ACE_M84"));
102        magazine.set_class("ACE_M84_HEDP");
103        assert_eq!(magazine.class(), Some("ACE_M84_HEDP"));
104    }
105
106    #[test]
107    fn ammo() {
108        let mut magazine = Magazine::new("ACE_M84".to_string(), 10);
109        assert_eq!(magazine.ammo(), Some(10));
110        magazine.set_ammo(20);
111        assert_eq!(magazine.ammo(), Some(20));
112    }
113
114    #[test]
115    fn from_arma() {
116        let magazine = Magazine::from_arma("[]".to_string()).unwrap();
117        assert!(!magazine.exists());
118        let magazine = Magazine::from_arma("[\"ACE_M84\", 10]".to_string()).unwrap();
119        assert!(magazine.exists());
120        assert_eq!(magazine.class(), Some("ACE_M84"));
121        assert_eq!(magazine.ammo(), Some(10));
122    }
123
124    #[test]
125    fn to_arma() {
126        let magazine = Magazine::new("ACE_M84".to_string(), 10);
127        assert_eq!(
128            magazine.to_arma(),
129            Value::Array(vec![
130                Value::String("ACE_M84".to_string()),
131                Value::Number(10.0),
132            ])
133        );
134    }
135}