steam_vdf_parser/value/
types.rs1use alloc::borrow::Cow;
4use indexmap::IndexMap;
5
6use super::hasher::DefaultHashBuilder;
7
8pub(crate) type Key<'text> = Cow<'text, str>;
10
11#[derive(Clone, Debug, PartialEq)]
13pub enum Value<'text> {
14 Str(Cow<'text, str>),
16 Obj(Obj<'text>),
18 I32(i32),
20 U64(u64),
22 Float(f32),
24 Pointer(u32),
26 Color([u8; 4]),
28}
29
30impl<'text> Value<'text> {
31 pub fn is_str(&self) -> bool {
33 matches!(self, Value::Str(_))
34 }
35
36 pub fn is_obj(&self) -> bool {
38 matches!(self, Value::Obj(_))
39 }
40
41 pub fn is_i32(&self) -> bool {
43 matches!(self, Value::I32(_))
44 }
45
46 pub fn is_u64(&self) -> bool {
48 matches!(self, Value::U64(_))
49 }
50
51 pub fn is_float(&self) -> bool {
53 matches!(self, Value::Float(_))
54 }
55
56 pub fn is_pointer(&self) -> bool {
58 matches!(self, Value::Pointer(_))
59 }
60
61 pub fn is_color(&self) -> bool {
63 matches!(self, Value::Color(_))
64 }
65
66 pub fn as_str(&self) -> Option<&str> {
68 match self {
69 Value::Str(s) => Some(s.as_ref()),
70 _ => None,
71 }
72 }
73
74 pub fn as_obj(&self) -> Option<&Obj<'text>> {
76 match self {
77 Value::Obj(obj) => Some(obj),
78 _ => None,
79 }
80 }
81
82 pub fn as_obj_mut(&mut self) -> Option<&mut Obj<'text>> {
84 match self {
85 Value::Obj(obj) => Some(obj),
86 _ => None,
87 }
88 }
89
90 pub fn as_i32(&self) -> Option<i32> {
92 match self {
93 Value::I32(n) => Some(*n),
94 _ => None,
95 }
96 }
97
98 pub fn as_u64(&self) -> Option<u64> {
100 match self {
101 Value::U64(n) => Some(*n),
102 _ => None,
103 }
104 }
105
106 pub fn as_float(&self) -> Option<f32> {
108 match self {
109 Value::Float(n) => Some(*n),
110 _ => None,
111 }
112 }
113
114 pub fn as_pointer(&self) -> Option<u32> {
116 match self {
117 Value::Pointer(n) => Some(*n),
118 _ => None,
119 }
120 }
121
122 pub fn as_color(&self) -> Option<[u8; 4]> {
124 match self {
125 Value::Color(c) => Some(*c),
126 _ => None,
127 }
128 }
129
130 pub fn get(&self, key: &str) -> Option<&Value<'text>> {
134 self.as_obj()?.get(key)
135 }
136
137 pub fn get_path(&self, path: &[&str]) -> Option<&Value<'text>> {
141 let mut current = self;
142 for key in path {
143 current = current.get(key)?;
144 }
145 Some(current)
146 }
147
148 pub fn get_str(&self, path: &[&str]) -> Option<&str> {
150 self.get_path(path)?.as_str()
151 }
152
153 pub fn get_obj(&self, path: &[&str]) -> Option<&Obj<'text>> {
155 self.get_path(path)?.as_obj()
156 }
157
158 pub fn get_i32(&self, path: &[&str]) -> Option<i32> {
160 self.get_path(path)?.as_i32()
161 }
162
163 pub fn get_u64(&self, path: &[&str]) -> Option<u64> {
165 self.get_path(path)?.as_u64()
166 }
167
168 pub fn get_float(&self, path: &[&str]) -> Option<f32> {
170 self.get_path(path)?.as_float()
171 }
172}
173
174#[derive(Clone, Debug, PartialEq)]
180pub struct Obj<'text> {
181 pub(crate) inner: IndexMap<Key<'text>, Value<'text>, DefaultHashBuilder>,
182}
183
184impl<'text> Obj<'text> {
185 pub fn new() -> Self {
187 Self {
188 inner: IndexMap::with_hasher(DefaultHashBuilder::default()),
189 }
190 }
191
192 pub fn len(&self) -> usize {
194 self.inner.len()
195 }
196
197 pub fn is_empty(&self) -> bool {
199 self.inner.is_empty()
200 }
201
202 pub fn get(&self, key: &str) -> Option<&Value<'text>> {
204 self.inner.get(key)
205 }
206
207 pub fn iter(&self) -> impl Iterator<Item = (&Key<'text>, &Value<'text>)> {
209 self.inner.iter()
210 }
211
212 pub fn keys(&self) -> impl Iterator<Item = &str> {
214 self.inner.keys().map(|k| k.as_ref())
215 }
216
217 pub fn values(&self) -> impl Iterator<Item = &Value<'text>> {
219 self.inner.values()
220 }
221
222 pub fn contains_key(&self, key: &str) -> bool {
224 self.inner.contains_key(key)
225 }
226
227 pub fn get_mut(&mut self, key: &str) -> Option<&mut Value<'text>> {
229 self.inner.get_mut(key)
230 }
231
232 pub fn insert(
236 &mut self,
237 key: impl Into<Key<'text>>,
238 value: Value<'text>,
239 ) -> Option<Value<'text>> {
240 self.inner.insert(key.into(), value)
241 }
242
243 pub fn remove(&mut self, key: &str) -> Option<Value<'text>> {
250 self.inner.shift_remove(key)
251 }
252
253 pub fn swap_remove(&mut self, key: &str) -> Option<Value<'text>> {
260 self.inner.swap_remove(key)
261 }
262}
263
264#[derive(Clone, Debug, PartialEq)]
268pub struct Vdf<'text> {
269 key: Key<'text>,
270 value: Value<'text>,
271}
272
273impl<'text> Vdf<'text> {
274 pub fn new(key: impl Into<Key<'text>>, value: Value<'text>) -> Self {
276 Self {
277 key: key.into(),
278 value,
279 }
280 }
281
282 pub fn key(&self) -> &str {
284 &self.key
285 }
286
287 pub fn value(&self) -> &Value<'text> {
289 &self.value
290 }
291
292 pub fn value_mut(&mut self) -> &mut Value<'text> {
294 &mut self.value
295 }
296
297 pub fn into_parts(self) -> (Cow<'text, str>, Value<'text>) {
299 (self.key, self.value)
300 }
301
302 pub fn is_obj(&self) -> bool {
304 self.value.is_obj()
305 }
306
307 pub fn as_obj(&self) -> Option<&Obj<'text>> {
309 self.value.as_obj()
310 }
311
312 pub fn get(&self, key: &str) -> Option<&Value<'text>> {
314 self.value.get(key)
315 }
316
317 pub fn get_path(&self, path: &[&str]) -> Option<&Value<'text>> {
319 self.value.get_path(path)
320 }
321
322 pub fn get_str(&self, path: &[&str]) -> Option<&str> {
324 self.value.get_str(path)
325 }
326
327 pub fn get_obj(&self, path: &[&str]) -> Option<&Obj<'text>> {
329 self.value.get_obj(path)
330 }
331
332 pub fn get_i32(&self, path: &[&str]) -> Option<i32> {
334 self.value.get_i32(path)
335 }
336
337 pub fn get_u64(&self, path: &[&str]) -> Option<u64> {
339 self.value.get_u64(path)
340 }
341
342 pub fn get_float(&self, path: &[&str]) -> Option<f32> {
344 self.value.get_float(path)
345 }
346}