msg_tool\ext/
psb.rs

1//!Extensions for emote_psb crate.
2use emote_psb::VirtualPsb;
3use emote_psb::header::PsbHeader;
4use emote_psb::types::collection::*;
5use emote_psb::types::number::*;
6use emote_psb::types::reference::*;
7use emote_psb::types::string::*;
8use emote_psb::types::*;
9#[cfg(feature = "json")]
10use json::JsonValue;
11use serde::ser::SerializeStruct;
12use serde::{Deserialize, Serialize};
13use std::cmp::PartialEq;
14use std::collections::HashMap;
15use std::ops::{Index, IndexMut};
16
17const NONE: PsbValueFixed = PsbValueFixed::None;
18
19#[derive(Debug, Serialize, Deserialize)]
20/// Represents of a PSB value.
21pub enum PsbValueFixed {
22    /// No value.
23    None,
24    /// Represents a null value.
25    Null,
26    /// Represents a boolean value.
27    Bool(bool),
28    /// Represents a number value.
29    Number(PsbNumber),
30    /// Represents an array of integers.
31    IntArray(PsbUintArray),
32    /// Represents a string value.
33    String(PsbString),
34    /// Represents a list of PSB values.
35    List(PsbListFixed),
36    /// Represents an object with key-value pairs.
37    Object(PsbObjectFixed),
38    /// Represents a resource reference.
39    Resource(PsbResourceRef),
40    /// Represents an extra resource reference.
41    ExtraResource(PsbExtraRef),
42    /// Represents a compiler number.
43    CompilerNumber,
44    /// Represents a compiler string.
45    CompilerString,
46    /// Represents a compiler resource.
47    CompilerResource,
48    /// Represents a compiler decimal.
49    CompilerDecimal,
50    /// Represents a compiler array.
51    CompilerArray,
52    /// Represents a compiler boolean.
53    CompilerBool,
54    /// Represents a compiler binary tree.
55    CompilerBinaryTree,
56}
57
58impl PsbValueFixed {
59    /// Converts this value to original PSB value type.
60    pub fn to_psb(self) -> PsbValue {
61        match self {
62            PsbValueFixed::None => PsbValue::None,
63            PsbValueFixed::Null => PsbValue::Null,
64            PsbValueFixed::Bool(b) => PsbValue::Bool(b),
65            PsbValueFixed::Number(n) => PsbValue::Number(n),
66            PsbValueFixed::IntArray(arr) => PsbValue::IntArray(arr),
67            PsbValueFixed::String(s) => PsbValue::String(s),
68            PsbValueFixed::List(l) => PsbValue::List(l.to_psb()),
69            PsbValueFixed::Object(o) => PsbValue::Object(o.to_psb()),
70            PsbValueFixed::Resource(r) => PsbValue::Resource(r),
71            PsbValueFixed::ExtraResource(er) => PsbValue::ExtraResource(er),
72            PsbValueFixed::CompilerNumber => PsbValue::CompilerNumber,
73            PsbValueFixed::CompilerString => PsbValue::CompilerString,
74            PsbValueFixed::CompilerResource => PsbValue::CompilerResource,
75            PsbValueFixed::CompilerDecimal => PsbValue::CompilerDecimal,
76            PsbValueFixed::CompilerArray => PsbValue::CompilerArray,
77            PsbValueFixed::CompilerBool => PsbValue::CompilerBool,
78            PsbValueFixed::CompilerBinaryTree => PsbValue::CompilerBinaryTree,
79        }
80    }
81
82    /// Returns true if this value is a list.
83    pub fn is_list(&self) -> bool {
84        matches!(self, PsbValueFixed::List(_))
85    }
86
87    /// Returns true if this value is an object.
88    pub fn is_object(&self) -> bool {
89        matches!(self, PsbValueFixed::Object(_))
90    }
91
92    /// Returns true if this value is a string or null.
93    pub fn is_string_or_null(&self) -> bool {
94        self.is_string() || self.is_null()
95    }
96
97    /// Returns true if this value is a string.
98    pub fn is_string(&self) -> bool {
99        matches!(self, PsbValueFixed::String(_))
100    }
101
102    /// Returns true if this value is none.
103    pub fn is_none(&self) -> bool {
104        matches!(self, PsbValueFixed::None)
105    }
106
107    /// Returns true if this value is null.
108    pub fn is_null(&self) -> bool {
109        matches!(self, PsbValueFixed::Null)
110    }
111
112    /// Sets the value of this PSB value to a new string.
113    pub fn set_str(&mut self, value: &str) {
114        match self {
115            PsbValueFixed::String(s) => {
116                let s = s.string_mut();
117                s.clear();
118                s.push_str(value);
119            }
120            _ => {
121                *self = PsbValueFixed::String(PsbString::from(value.to_owned()));
122            }
123        }
124    }
125
126    /// Sets the value of this PSB value to a new string.
127    pub fn set_string(&mut self, value: String) {
128        self.set_str(&value);
129    }
130
131    /// Returns the value as a boolean, if it is a boolean.
132    pub fn as_u8(&self) -> Option<u8> {
133        self.as_i64().map(|n| n.try_into().ok()).flatten()
134    }
135
136    /// Returns the value as a [u32], if it is a number.
137    pub fn as_u32(&self) -> Option<u32> {
138        self.as_i64().map(|n| n as u32)
139    }
140
141    /// Returns the value as a [i64], if it is a number.
142    pub fn as_i64(&self) -> Option<i64> {
143        match self {
144            PsbValueFixed::Number(n) => match n {
145                PsbNumber::Integer(n) => Some(*n),
146                _ => None,
147            },
148            _ => None,
149        }
150    }
151
152    /// Returns the value as a string, if it is a string.
153    pub fn as_str(&self) -> Option<&str> {
154        match self {
155            PsbValueFixed::String(s) => Some(s.string()),
156            _ => None,
157        }
158    }
159
160    /// Returns the lengtho of a list or object.
161    pub fn len(&self) -> usize {
162        match self {
163            PsbValueFixed::List(l) => l.len(),
164            PsbValueFixed::Object(o) => o.values.len(),
165            _ => 0,
166        }
167    }
168
169    /// Returns a iterator over the entries of an object.
170    pub fn entries(&self) -> ObjectIter<'_> {
171        match self {
172            PsbValueFixed::Object(o) => o.iter(),
173            _ => ObjectIter::empty(),
174        }
175    }
176
177    /// Returns a mutable iterator over the entries of an object.
178    pub fn entries_mut(&mut self) -> ObjectIterMut<'_> {
179        match self {
180            PsbValueFixed::Object(o) => o.iter_mut(),
181            _ => ObjectIterMut::empty(),
182        }
183    }
184
185    /// Returns a iterator over the members of a list.
186    pub fn members(&self) -> ListIter<'_> {
187        match self {
188            PsbValueFixed::List(l) => l.iter(),
189            _ => ListIter::empty(),
190        }
191    }
192
193    /// Returns a mutable iterator over the members of a list.
194    pub fn members_mut(&mut self) -> ListIterMut<'_> {
195        match self {
196            PsbValueFixed::List(l) => l.iter_mut(),
197            _ => ListIterMut::empty(),
198        }
199    }
200
201    /// Returns the resource ID if this value is a resource reference.
202    pub fn resource_id(&self) -> Option<u64> {
203        match self {
204            PsbValueFixed::Resource(r) => Some(r.resource_ref),
205            _ => None,
206        }
207    }
208
209    /// Converts this value to a JSON value, if possible.
210    #[cfg(feature = "json")]
211    pub fn to_json(&self) -> Option<JsonValue> {
212        match self {
213            PsbValueFixed::Null => Some(JsonValue::Null),
214            PsbValueFixed::Bool(b) => Some(JsonValue::Boolean(*b)),
215            PsbValueFixed::Number(n) => match n {
216                PsbNumber::Integer(i) => Some(JsonValue::Number((*i).into())),
217                PsbNumber::Float(f) => Some(JsonValue::Number((*f).into())),
218                PsbNumber::Double(d) => Some(JsonValue::Number((*d).into())),
219            },
220            PsbValueFixed::String(s) => Some(JsonValue::String(s.string().to_owned())),
221            PsbValueFixed::Resource(s) => {
222                Some(JsonValue::String(format!("resource#{}", s.resource_ref)))
223            }
224            PsbValueFixed::ExtraResource(s) => Some(JsonValue::String(format!(
225                "extra_resource#{}",
226                s.extra_resource_ref
227            ))),
228            PsbValueFixed::IntArray(arr) => Some(JsonValue::Array(
229                arr.iter().map(|n| JsonValue::Number((*n).into())).collect(),
230            )),
231            PsbValueFixed::List(l) => Some(l.to_json()),
232            PsbValueFixed::Object(o) => Some(o.to_json()),
233            _ => None,
234        }
235    }
236
237    /// Converts a JSON value to a PSB value.
238    #[cfg(feature = "json")]
239    pub fn from_json(obj: &JsonValue) -> Self {
240        match obj {
241            JsonValue::Null => PsbValueFixed::Null,
242            JsonValue::Boolean(b) => PsbValueFixed::Bool(*b),
243            JsonValue::Number(n) => {
244                let data: f64 = (*n).into();
245                if data.fract() == 0.0 {
246                    PsbValueFixed::Number(PsbNumber::Integer(data as i64))
247                } else {
248                    PsbValueFixed::Number(PsbNumber::Float(data as f32))
249                }
250            }
251            JsonValue::String(s) => {
252                if s.starts_with("resource#") {
253                    if let Ok(id) = s[9..].parse::<u64>() {
254                        return PsbValueFixed::Resource(PsbResourceRef { resource_ref: id });
255                    }
256                } else if s.starts_with("extra_resource#") {
257                    if let Ok(id) = s[16..].parse::<u64>() {
258                        return PsbValueFixed::ExtraResource(PsbExtraRef {
259                            extra_resource_ref: id,
260                        });
261                    }
262                }
263                PsbValueFixed::String(PsbString::from(s.clone()))
264            }
265            JsonValue::Array(arr) => {
266                let values: Vec<PsbValueFixed> = arr.iter().map(PsbValueFixed::from_json).collect();
267                PsbValueFixed::List(PsbListFixed { values })
268            }
269            JsonValue::Object(obj) => {
270                let mut values = HashMap::new();
271                for (key, value) in obj.iter() {
272                    values.insert(key.to_owned(), PsbValueFixed::from_json(value));
273                }
274                PsbValueFixed::Object(PsbObjectFixed { values })
275            }
276            JsonValue::Short(n) => {
277                let s = n.as_str();
278                if s.starts_with("resource#") {
279                    if let Ok(id) = s[9..].parse::<u64>() {
280                        return PsbValueFixed::Resource(PsbResourceRef { resource_ref: id });
281                    }
282                } else if s.starts_with("extra_resource#") {
283                    if let Ok(id) = s[16..].parse::<u64>() {
284                        return PsbValueFixed::ExtraResource(PsbExtraRef {
285                            extra_resource_ref: id,
286                        });
287                    }
288                }
289                PsbValueFixed::String(PsbString::from(s.to_owned()))
290            }
291        }
292    }
293}
294
295impl Index<usize> for PsbValueFixed {
296    type Output = PsbValueFixed;
297
298    fn index(&self, index: usize) -> &Self::Output {
299        match self {
300            PsbValueFixed::List(l) => &l.values[index],
301            _ => &NONE,
302        }
303    }
304}
305
306impl IndexMut<usize> for PsbValueFixed {
307    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
308        match self {
309            PsbValueFixed::List(l) => {
310                if index < l.values.len() {
311                    &mut l.values[index]
312                } else {
313                    l.values.push(NONE);
314                    l.values.last_mut().unwrap()
315                }
316            }
317            _ => {
318                *self = PsbValueFixed::List(PsbListFixed { values: vec![NONE] });
319                self.index_mut(0)
320            }
321        }
322    }
323}
324
325impl<'a> Index<&'a str> for PsbValueFixed {
326    type Output = PsbValueFixed;
327
328    fn index(&self, index: &'a str) -> &Self::Output {
329        match self {
330            PsbValueFixed::Object(o) => &o[index],
331            _ => &NONE,
332        }
333    }
334}
335
336impl<'a> Index<&'a String> for PsbValueFixed {
337    type Output = PsbValueFixed;
338
339    fn index(&self, index: &'a String) -> &Self::Output {
340        self.index(index.as_str())
341    }
342}
343
344impl Index<String> for PsbValueFixed {
345    type Output = PsbValueFixed;
346
347    fn index(&self, index: String) -> &Self::Output {
348        self.index(index.as_str())
349    }
350}
351
352impl IndexMut<&str> for PsbValueFixed {
353    fn index_mut(&mut self, index: &str) -> &mut Self::Output {
354        match self {
355            PsbValueFixed::Object(o) => o.index_mut(index),
356            _ => {
357                *self = PsbValueFixed::Object(PsbObjectFixed {
358                    values: HashMap::new(),
359                });
360                self.index_mut(index)
361            }
362        }
363    }
364}
365
366impl IndexMut<&String> for PsbValueFixed {
367    fn index_mut(&mut self, index: &String) -> &mut Self::Output {
368        self.index_mut(index.as_str())
369    }
370}
371
372impl IndexMut<String> for PsbValueFixed {
373    fn index_mut(&mut self, index: String) -> &mut Self::Output {
374        self.index_mut(index.as_str())
375    }
376}
377
378impl Clone for PsbValueFixed {
379    fn clone(&self) -> Self {
380        match self {
381            PsbValueFixed::None => PsbValueFixed::None,
382            PsbValueFixed::Null => PsbValueFixed::Null,
383            PsbValueFixed::Bool(b) => PsbValueFixed::Bool(*b),
384            PsbValueFixed::Number(n) => PsbValueFixed::Number(n.clone()),
385            PsbValueFixed::IntArray(arr) => PsbValueFixed::IntArray(arr.clone()),
386            PsbValueFixed::String(s) => PsbValueFixed::String(PsbString::from(s.string().clone())),
387            PsbValueFixed::List(l) => PsbValueFixed::List(l.clone()),
388            PsbValueFixed::Object(o) => PsbValueFixed::Object(o.clone()),
389            PsbValueFixed::Resource(r) => PsbValueFixed::Resource(r.clone()),
390            PsbValueFixed::ExtraResource(er) => PsbValueFixed::ExtraResource(er.clone()),
391            PsbValueFixed::CompilerNumber => PsbValueFixed::CompilerNumber,
392            PsbValueFixed::CompilerString => PsbValueFixed::CompilerString,
393            PsbValueFixed::CompilerResource => PsbValueFixed::CompilerResource,
394            PsbValueFixed::CompilerDecimal => PsbValueFixed::CompilerDecimal,
395            PsbValueFixed::CompilerArray => PsbValueFixed::CompilerArray,
396            PsbValueFixed::CompilerBool => PsbValueFixed::CompilerBool,
397            PsbValueFixed::CompilerBinaryTree => PsbValueFixed::CompilerBinaryTree,
398        }
399    }
400}
401
402impl PartialEq<String> for PsbValueFixed {
403    fn eq(&self, other: &String) -> bool {
404        self == other.as_str()
405    }
406}
407
408impl PartialEq<str> for PsbValueFixed {
409    fn eq(&self, other: &str) -> bool {
410        match self {
411            PsbValueFixed::String(s) => s.string() == other,
412            _ => false,
413        }
414    }
415}
416
417impl<'a> PartialEq<&'a str> for PsbValueFixed {
418    fn eq(&self, other: &&'a str) -> bool {
419        self == *other
420    }
421}
422
423/// Trait to convert a PSB value to a fixed PSB value.
424pub trait PsbValueExt {
425    /// Converts this PSB value to a fixed PSB value.
426    fn to_psb_fixed(self) -> PsbValueFixed;
427}
428
429impl PsbValueExt for PsbValue {
430    fn to_psb_fixed(self) -> PsbValueFixed {
431        match self {
432            PsbValue::None => PsbValueFixed::None,
433            PsbValue::Null => PsbValueFixed::Null,
434            PsbValue::Bool(b) => PsbValueFixed::Bool(b),
435            PsbValue::Number(n) => PsbValueFixed::Number(n),
436            PsbValue::IntArray(arr) => PsbValueFixed::IntArray(arr),
437            PsbValue::String(s) => PsbValueFixed::String(s),
438            PsbValue::List(l) => PsbValueFixed::List(PsbList::to_psb_fixed(l)),
439            PsbValue::Object(o) => PsbValueFixed::Object(PsbObject::to_psb_fixed(o)),
440            PsbValue::Resource(r) => PsbValueFixed::Resource(r),
441            PsbValue::ExtraResource(er) => PsbValueFixed::ExtraResource(er),
442            PsbValue::CompilerNumber => PsbValueFixed::CompilerNumber,
443            PsbValue::CompilerString => PsbValueFixed::CompilerString,
444            PsbValue::CompilerResource => PsbValueFixed::CompilerResource,
445            PsbValue::CompilerDecimal => PsbValueFixed::CompilerDecimal,
446            PsbValue::CompilerArray => PsbValueFixed::CompilerArray,
447            PsbValue::CompilerBool => PsbValueFixed::CompilerBool,
448            PsbValue::CompilerBinaryTree => PsbValueFixed::CompilerBinaryTree,
449        }
450    }
451}
452
453#[derive(Clone, Debug, Serialize, Deserialize)]
454#[serde(transparent)]
455/// Represents a PSB list of PSB values.
456pub struct PsbListFixed {
457    /// The values in the list.
458    pub values: Vec<PsbValueFixed>,
459}
460
461impl PsbListFixed {
462    /// Converts this PSB list to a original PSB list.
463    pub fn to_psb(self) -> PsbList {
464        let v: Vec<_> = self.values.into_iter().map(|v| v.to_psb()).collect();
465        PsbList::from(v)
466    }
467
468    /// Returns a iterator over the values in the list.
469    pub fn iter(&self) -> ListIter<'_> {
470        ListIter {
471            inner: self.values.iter(),
472        }
473    }
474
475    /// Returns a mutable iterator over the values in the list.
476    pub fn iter_mut(&mut self) -> ListIterMut<'_> {
477        ListIterMut {
478            inner: self.values.iter_mut(),
479        }
480    }
481
482    /// Returns a reference to the values in the list.
483    pub fn values(&self) -> &Vec<PsbValueFixed> {
484        &self.values
485    }
486
487    /// Returns the length of the list.
488    pub fn len(&self) -> usize {
489        self.values.len()
490    }
491
492    /// Converts this PSB list to a JSON value.
493    #[cfg(feature = "json")]
494    pub fn to_json(&self) -> JsonValue {
495        let data: Vec<_> = self.values.iter().filter_map(|v| v.to_json()).collect();
496        JsonValue::Array(data)
497    }
498}
499
500impl Index<usize> for PsbListFixed {
501    type Output = PsbValueFixed;
502
503    fn index(&self, index: usize) -> &Self::Output {
504        self.values.get(index).unwrap_or(&NONE)
505    }
506}
507
508impl IndexMut<usize> for PsbListFixed {
509    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
510        if index < self.values.len() {
511            &mut self.values[index]
512        } else {
513            self.values.push(NONE);
514            self.values.last_mut().unwrap()
515        }
516    }
517}
518
519/// Iterator for a slice of PSB values in a list.
520pub struct ListIter<'a> {
521    inner: std::slice::Iter<'a, PsbValueFixed>,
522}
523
524impl<'a> ListIter<'a> {
525    /// Creates an empty iterator.
526    pub fn empty() -> Self {
527        ListIter {
528            inner: Default::default(),
529        }
530    }
531}
532
533impl<'a> Iterator for ListIter<'a> {
534    type Item = &'a PsbValueFixed;
535
536    #[inline(always)]
537    fn next(&mut self) -> Option<Self::Item> {
538        self.inner.next()
539    }
540}
541
542impl<'a> ExactSizeIterator for ListIter<'a> {
543    fn len(&self) -> usize {
544        self.inner.len()
545    }
546}
547
548impl<'a> DoubleEndedIterator for ListIter<'a> {
549    #[inline(always)]
550    fn next_back(&mut self) -> Option<Self::Item> {
551        self.inner.next_back()
552    }
553}
554
555/// Mutable iterator for a slice of PSB values in a list.
556pub struct ListIterMut<'a> {
557    inner: std::slice::IterMut<'a, PsbValueFixed>,
558}
559
560impl<'a> ListIterMut<'a> {
561    /// Creates an empty mutable iterator.
562    pub fn empty() -> Self {
563        ListIterMut {
564            inner: Default::default(),
565        }
566    }
567}
568
569impl<'a> Iterator for ListIterMut<'a> {
570    type Item = &'a mut PsbValueFixed;
571
572    #[inline(always)]
573    fn next(&mut self) -> Option<Self::Item> {
574        self.inner.next()
575    }
576}
577
578impl<'a> ExactSizeIterator for ListIterMut<'a> {
579    fn len(&self) -> usize {
580        self.inner.len()
581    }
582}
583
584impl<'a> DoubleEndedIterator for ListIterMut<'a> {
585    #[inline(always)]
586    fn next_back(&mut self) -> Option<Self::Item> {
587        self.inner.next_back()
588    }
589}
590
591/// Trait to convert a PSB list to a fixed PSB list.
592pub trait PsbListExt {
593    /// Converts this PSB list to a fixed PSB list.
594    fn to_psb_fixed(self) -> PsbListFixed;
595}
596
597impl PsbListExt for PsbList {
598    fn to_psb_fixed(self) -> PsbListFixed {
599        let values: Vec<_> = self
600            .unwrap()
601            .into_iter()
602            .map(PsbValue::to_psb_fixed)
603            .collect();
604        PsbListFixed { values }
605    }
606}
607
608#[derive(Clone, Debug, Serialize, Deserialize)]
609#[serde(transparent)]
610/// Represents a PSB object with key-value pairs.
611pub struct PsbObjectFixed {
612    /// The key-value pairs in the object.
613    pub values: HashMap<String, PsbValueFixed>,
614}
615
616impl PsbObjectFixed {
617    /// Creates a new empty PSB object.
618    pub fn to_psb(self) -> PsbObject {
619        let mut hash_map = HashMap::new();
620        for (key, value) in self.values {
621            hash_map.insert(key, value.to_psb());
622        }
623        PsbObject::from(hash_map)
624    }
625
626    /// Gets a reference of value in the object by key.
627    pub fn get_value(&self, key: &str) -> Option<&PsbValueFixed> {
628        self.values.get(key)
629    }
630
631    /// Returns a iterator over the entries of the object.
632    pub fn iter(&self) -> ObjectIter<'_> {
633        ObjectIter {
634            inner: self.values.iter(),
635        }
636    }
637
638    /// Returns a mutable iterator over the entries of the object.
639    pub fn iter_mut(&mut self) -> ObjectIterMut<'_> {
640        ObjectIterMut {
641            inner: self.values.iter_mut(),
642        }
643    }
644
645    /// Converts this PSB object to a JSON value.
646    #[cfg(feature = "json")]
647    pub fn to_json(&self) -> JsonValue {
648        let mut obj = json::object::Object::new();
649        for (key, value) in &self.values {
650            if let Some(json_value) = value.to_json() {
651                obj.insert(key, json_value);
652            }
653        }
654        JsonValue::Object(obj)
655    }
656
657    /// Converts a JSON object to a PSB object.
658    #[cfg(feature = "json")]
659    pub fn from_json(obj: &JsonValue) -> Self {
660        let mut values = HashMap::new();
661        for (key, value) in obj.entries() {
662            values.insert(key.to_owned(), PsbValueFixed::from_json(value));
663        }
664        PsbObjectFixed { values }
665    }
666}
667
668impl<'a> Index<&'a str> for PsbObjectFixed {
669    type Output = PsbValueFixed;
670
671    fn index(&self, index: &'a str) -> &Self::Output {
672        self.values.get(index).unwrap_or(&NONE)
673    }
674}
675
676impl<'a> Index<&'a String> for PsbObjectFixed {
677    type Output = PsbValueFixed;
678
679    fn index(&self, index: &'a String) -> &Self::Output {
680        self.index(index.as_str())
681    }
682}
683
684impl Index<String> for PsbObjectFixed {
685    type Output = PsbValueFixed;
686
687    fn index(&self, index: String) -> &Self::Output {
688        self.index(index.as_str())
689    }
690}
691
692impl<'a> IndexMut<&'a str> for PsbObjectFixed {
693    fn index_mut(&mut self, index: &'a str) -> &mut Self::Output {
694        self.values.entry(index.to_string()).or_insert(NONE)
695    }
696}
697
698impl<'a> IndexMut<&'a String> for PsbObjectFixed {
699    fn index_mut(&mut self, index: &'a String) -> &mut Self::Output {
700        self.index_mut(index.as_str())
701    }
702}
703
704impl IndexMut<String> for PsbObjectFixed {
705    fn index_mut(&mut self, index: String) -> &mut Self::Output {
706        self.values.entry(index).or_insert(NONE)
707    }
708}
709
710/// Trait to convert a PSB object to a fixed PSB object.
711pub trait PsbObjectExt {
712    /// Converts this PSB object to a fixed PSB object.
713    fn to_psb_fixed(self) -> PsbObjectFixed;
714}
715
716impl PsbObjectExt for PsbObject {
717    fn to_psb_fixed(self) -> PsbObjectFixed {
718        let mut hash_map = HashMap::new();
719        for (key, value) in self.unwrap() {
720            hash_map.insert(key, PsbValue::to_psb_fixed(value));
721        }
722        PsbObjectFixed { values: hash_map }
723    }
724}
725
726/// Iterator for a slice of PSB values in an object.
727pub struct ObjectIter<'a> {
728    inner: std::collections::hash_map::Iter<'a, String, PsbValueFixed>,
729}
730
731impl<'a> ObjectIter<'a> {
732    /// Creates an empty iterator.
733    pub fn empty() -> Self {
734        ObjectIter {
735            inner: Default::default(),
736        }
737    }
738}
739
740impl<'a> Iterator for ObjectIter<'a> {
741    type Item = (&'a String, &'a PsbValueFixed);
742
743    #[inline(always)]
744    fn next(&mut self) -> Option<Self::Item> {
745        self.inner.next()
746    }
747}
748impl<'a> ExactSizeIterator for ObjectIter<'a> {
749    fn len(&self) -> usize {
750        self.inner.len()
751    }
752}
753
754/// Mutable iterator for a slice of PSB values in an object.
755pub struct ObjectIterMut<'a> {
756    inner: std::collections::hash_map::IterMut<'a, String, PsbValueFixed>,
757}
758
759impl<'a> ObjectIterMut<'a> {
760    /// Creates an empty mutable iterator.
761    pub fn empty() -> Self {
762        ObjectIterMut {
763            inner: Default::default(),
764        }
765    }
766}
767
768impl<'a> Iterator for ObjectIterMut<'a> {
769    type Item = (&'a String, &'a mut PsbValueFixed);
770
771    #[inline(always)]
772    fn next(&mut self) -> Option<Self::Item> {
773        self.inner.next()
774    }
775}
776
777impl<'a> ExactSizeIterator for ObjectIterMut<'a> {
778    fn len(&self) -> usize {
779        self.inner.len()
780    }
781}
782
783/// Represents a fixed version of a virtual PSB.
784#[derive(Clone, Debug)]
785pub struct VirtualPsbFixed {
786    header: PsbHeader,
787    resources: Vec<Vec<u8>>,
788    extra: Vec<Vec<u8>>,
789    root: PsbObjectFixed,
790}
791
792impl Serialize for VirtualPsbFixed {
793    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
794    where
795        S: serde::Serializer,
796    {
797        let mut state = serializer.serialize_struct("VirtualPsbFixed", 3)?;
798        state.serialize_field("version", &self.header.version)?;
799        state.serialize_field("encryption", &self.header.encryption)?;
800        state.serialize_field("data", &self.root)?;
801        state.end()
802    }
803}
804
805#[derive(Deserialize)]
806pub struct VirtualPsbFixedData {
807    version: u16,
808    encryption: u16,
809    data: PsbObjectFixed,
810}
811
812impl VirtualPsbFixed {
813    /// Creates a new fixed virtual PSB.
814    pub fn new(
815        header: PsbHeader,
816        resources: Vec<Vec<u8>>,
817        extra: Vec<Vec<u8>>,
818        root: PsbObjectFixed,
819    ) -> Self {
820        Self {
821            header,
822            resources,
823            extra,
824            root,
825        }
826    }
827
828    /// Returns the header of the PSB.
829    pub fn header(&self) -> PsbHeader {
830        self.header
831    }
832
833    /// Returns a reference to the resources of the PSB.
834    pub fn resources(&self) -> &Vec<Vec<u8>> {
835        &self.resources
836    }
837
838    /// Returns a mutable reference to the resources of the PSB.
839    pub fn resources_mut(&mut self) -> &mut Vec<Vec<u8>> {
840        &mut self.resources
841    }
842
843    /// Returns a reference to the extra resources of the PSB.
844    pub fn extra(&self) -> &Vec<Vec<u8>> {
845        &self.extra
846    }
847
848    /// Returns a mutable reference to the extra resources of the PSB.
849    pub fn extra_mut(&mut self) -> &mut Vec<Vec<u8>> {
850        &mut self.extra
851    }
852
853    /// Returns a reference to the root object of the PSB.
854    pub fn root(&self) -> &PsbObjectFixed {
855        &self.root
856    }
857
858    /// Returns a mutable reference to the root object of the PSB.
859    pub fn root_mut(&mut self) -> &mut PsbObjectFixed {
860        &mut self.root
861    }
862
863    /// Sets the root of the PSB.
864    pub fn set_root(&mut self, root: PsbObjectFixed) {
865        self.root = root;
866    }
867
868    /// Unwraps the PSB into its components.
869    pub fn unwrap(self) -> (PsbHeader, Vec<Vec<u8>>, Vec<Vec<u8>>, PsbObjectFixed) {
870        (self.header, self.resources, self.extra, self.root)
871    }
872
873    /// Converts this fixed PSB to a virtual PSB.
874    pub fn to_psb(self) -> VirtualPsb {
875        let (header, resources, extra, root) = self.unwrap();
876        VirtualPsb::new(header, resources, extra, root.to_psb())
877    }
878
879    /// Converts json object to a fixed PSB.
880    #[cfg(feature = "json")]
881    pub fn from_json(&mut self, obj: &JsonValue) -> Result<(), anyhow::Error> {
882        let version = obj["version"]
883            .as_u16()
884            .ok_or_else(|| anyhow::anyhow!("Invalid PSB version"))?;
885        let encryption = obj["encryption"]
886            .as_u16()
887            .ok_or_else(|| anyhow::anyhow!("Invalid PSB encryption"))?;
888        self.header.version = version;
889        self.header.encryption = encryption;
890        self.root = PsbObjectFixed::from_json(&obj["data"]);
891        Ok(())
892    }
893
894    pub fn set_data(&mut self, data: VirtualPsbFixedData) {
895        self.header.version = data.version;
896        self.header.encryption = data.encryption;
897        self.root = data.data;
898    }
899
900    /// Converts this fixed PSB to a JSON object.
901    #[cfg(feature = "json")]
902    pub fn to_json(&self) -> JsonValue {
903        json::object! {
904            "version": self.header.version,
905            "encryption": self.header.encryption,
906            "data": self.root.to_json(),
907        }
908    }
909}
910
911/// Trait to convert a virtual PSB to a fixed PSB.
912pub trait VirtualPsbExt {
913    /// Converts this virtual PSB to a fixed PSB.
914    fn to_psb_fixed(self) -> VirtualPsbFixed;
915}
916
917impl VirtualPsbExt for VirtualPsb {
918    fn to_psb_fixed(self) -> VirtualPsbFixed {
919        let (header, resources, extra, root) = self.unwrap();
920        VirtualPsbFixed::new(header, resources, extra, root.to_psb_fixed())
921    }
922}