arma_rs/value/loadout/
container.rs1use crate::{FromArma, FromArmaError, IntoArma, Value};
2
3use super::InventoryItem;
4
5#[derive(Debug, Default, Clone, PartialEq, Eq)]
6pub struct Container(Option<(String, Vec<InventoryItem>)>);
8impl Container {
9 #[must_use]
11 pub const fn new(class: String) -> Self {
12 Self(Some((class, vec![])))
13 }
14
15 #[must_use]
17 pub const fn exists(&self) -> bool {
18 self.0.is_some()
19 }
20
21 #[must_use]
23 pub fn class(&self) -> Option<&str> {
24 self.0.as_ref().map(|(class, _)| class.as_str())
25 }
26
27 pub fn set_class(&mut self, class: String) {
29 if let Some(container) = self.0.as_mut() {
30 container.0 = class;
31 } else {
32 self.0 = Some((class, vec![]));
33 }
34 }
35
36 #[must_use]
38 pub fn items(&self) -> Option<&Vec<InventoryItem>> {
39 self.0.as_ref().map(|(_, items)| items)
40 }
41
42 pub fn items_mut(&mut self) -> Option<&mut Vec<InventoryItem>> {
44 self.0.as_mut().map(|(_, items)| items)
45 }
46
47 #[must_use]
49 pub fn classes(&self) -> Vec<(String, u32)> {
50 let mut classes = vec![];
51 if let Some((class, items)) = &self.0 {
52 classes.push((class.clone(), 1));
53 for item in items {
54 classes.push((item.class().to_string(), item.count()));
55 }
56 }
57 classes
58 }
59}
60impl FromArma for Container {
61 fn from_arma(s: String) -> Result<Self, FromArmaError> {
62 if s == "[]" {
63 return Ok(Self(None));
64 }
65 <(String, Vec<InventoryItem>)>::from_arma(s).map(|(name, items)| Self(Some((name, items))))
66 }
67}
68impl IntoArma for Container {
69 fn to_arma(&self) -> Value {
70 self.0.as_ref().map_or_else(
71 || Value::Array(vec![]),
72 |container| {
73 Value::Array(vec![
74 Value::String(container.0.clone()),
75 Value::Array(container.1.iter().map(IntoArma::to_arma).collect()),
76 ])
77 },
78 )
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use crate::{loadout::InventoryItem, FromArma, IntoArma, Value};
85
86 use super::Container;
87
88 #[test]
89 fn exists() {
90 let container = Container::default();
91 assert!(!container.exists());
92 let container = Container::new("container".to_string());
93 assert!(container.exists());
94 }
95
96 #[test]
97 fn class() {
98 let container = Container::default();
99 assert!(container.class().is_none());
100 let mut container = Container::new("container".to_string());
101 assert_eq!(container.class().unwrap(), "container");
102 container.set_class("container2".to_string());
103 assert_eq!(container.class().unwrap(), "container2");
104 }
105
106 #[test]
107 fn items() {
108 let container = Container::default();
109 assert!(container.items().is_none());
110 let mut container = Container::new("container".to_string());
111 assert!(container.items().is_some());
112 let items = vec![
113 InventoryItem::new_item("item1".to_string(), 1),
114 InventoryItem::new_item("item2".to_string(), 2),
115 ];
116 container.0.as_mut().unwrap().1 = items.clone();
117 assert_eq!(container.items().unwrap(), &items);
118 }
119
120 #[test]
121 fn from_arma() {
122 let container = Container::from_arma("[]".to_string()).unwrap();
123 assert!(!container.exists());
124 let container =
125 Container::from_arma("[\"container\",[[\"item1\",1],[\"item2\",2]]]".to_string())
126 .unwrap();
127 assert!(container.exists());
128 assert_eq!(container.class().unwrap(), "container");
129 assert_eq!(
130 container.items().unwrap(),
131 &vec![
132 InventoryItem::new_item("item1".to_string(), 1),
133 InventoryItem::new_item("item2".to_string(), 2),
134 ]
135 );
136 }
137
138 #[test]
139 fn to_arma() {
140 let container = Container::default();
141 assert_eq!(container.to_arma(), Value::Array(vec![]));
142 let mut container = Container::new("container".to_string());
143 assert_eq!(
144 container.to_arma(),
145 Value::Array(vec![
146 Value::String("container".to_string()),
147 Value::Array(vec![]),
148 ])
149 );
150 let items = vec![
151 InventoryItem::new_item("item1".to_string(), 1),
152 InventoryItem::new_item("item2".to_string(), 2),
153 ];
154 container.0.as_mut().unwrap().1 = items;
155 assert_eq!(
156 container.to_arma(),
157 Value::Array(vec![
158 Value::String("container".to_string()),
159 Value::Array(vec![
160 Value::Array(vec![Value::String("item1".to_string()), Value::Number(1.0),]),
161 Value::Array(vec![Value::String("item2".to_string()), Value::Number(2.0),]),
162 ]),
163 ])
164 );
165 }
166
167 #[test]
168 fn classes() {
169 let container = Container::from_arma("[]".to_string()).unwrap();
170 assert!(!container.exists());
171 let container =
172 Container::from_arma("[\"container\",[[\"item1\",1],[\"item2\",2]]]".to_string())
173 .unwrap();
174 assert_eq!(
175 container.classes(),
176 vec![
177 ("container".to_string(), 1),
178 ("item1".to_string(), 1),
179 ("item2".to_string(), 2)
180 ]
181 );
182 }
183}