1use 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::{BTreeMap, HashMap};
15use std::ops::{Index, IndexMut};
16
17const NONE: PsbValueFixed = PsbValueFixed::None;
18
19#[derive(Debug, Serialize, Deserialize)]
20pub enum PsbValueFixed {
22 None,
24 Null,
26 Bool(bool),
28 Number(PsbNumber),
30 IntArray(PsbUintArray),
32 String(PsbString),
34 List(PsbListFixed),
36 Object(PsbObjectFixed),
38 Resource(PsbResourceRef),
40 ExtraResource(PsbExtraRef),
42 CompilerNumber,
44 CompilerString,
46 CompilerResource,
48 CompilerDecimal,
50 CompilerArray,
52 CompilerBool,
54 CompilerBinaryTree,
56}
57
58impl From<String> for PsbValueFixed {
59 fn from(value: String) -> Self {
60 PsbValueFixed::String(PsbString::from(value))
61 }
62}
63
64impl From<bool> for PsbValueFixed {
65 fn from(value: bool) -> Self {
66 PsbValueFixed::Bool(value)
67 }
68}
69
70impl From<i64> for PsbValueFixed {
71 fn from(value: i64) -> Self {
72 PsbValueFixed::Number(PsbNumber::Integer(value))
73 }
74}
75
76impl From<f64> for PsbValueFixed {
77 fn from(value: f64) -> Self {
78 PsbValueFixed::Number(PsbNumber::Double(value))
79 }
80}
81
82impl From<f32> for PsbValueFixed {
83 fn from(value: f32) -> Self {
84 PsbValueFixed::Number(PsbNumber::Float(value))
85 }
86}
87
88impl From<PsbObjectFixed> for PsbValueFixed {
89 fn from(value: PsbObjectFixed) -> Self {
90 PsbValueFixed::Object(value)
91 }
92}
93
94impl From<PsbListFixed> for PsbValueFixed {
95 fn from(value: PsbListFixed) -> Self {
96 PsbValueFixed::List(value)
97 }
98}
99
100impl From<&[PsbValueFixed]> for PsbValueFixed {
101 fn from(value: &[PsbValueFixed]) -> Self {
102 PsbValueFixed::List(PsbListFixed {
103 values: value.to_vec(),
104 })
105 }
106}
107
108impl PsbValueFixed {
109 pub fn to_psb(self, warn_on_none: bool) -> PsbValue {
111 match self {
112 PsbValueFixed::None => {
113 if warn_on_none {
114 eprintln!("Warning: PSB value is None, output script may broken.");
115 crate::COUNTER.inc_warning();
116 }
117 PsbValue::None
118 }
119 PsbValueFixed::Null => PsbValue::Null,
120 PsbValueFixed::Bool(b) => PsbValue::Bool(b),
121 PsbValueFixed::Number(n) => PsbValue::Number(n),
122 PsbValueFixed::IntArray(arr) => PsbValue::IntArray(arr),
123 PsbValueFixed::String(s) => PsbValue::String(s),
124 PsbValueFixed::List(l) => PsbValue::List(l.to_psb(warn_on_none)),
125 PsbValueFixed::Object(o) => PsbValue::Object(o.to_psb(warn_on_none)),
126 PsbValueFixed::Resource(r) => PsbValue::Resource(r),
127 PsbValueFixed::ExtraResource(er) => PsbValue::ExtraResource(er),
128 PsbValueFixed::CompilerNumber => PsbValue::CompilerNumber,
129 PsbValueFixed::CompilerString => PsbValue::CompilerString,
130 PsbValueFixed::CompilerResource => PsbValue::CompilerResource,
131 PsbValueFixed::CompilerDecimal => PsbValue::CompilerDecimal,
132 PsbValueFixed::CompilerArray => PsbValue::CompilerArray,
133 PsbValueFixed::CompilerBool => PsbValue::CompilerBool,
134 PsbValueFixed::CompilerBinaryTree => PsbValue::CompilerBinaryTree,
135 }
136 }
137
138 pub fn is_list(&self) -> bool {
140 matches!(self, PsbValueFixed::List(_))
141 }
142
143 pub fn is_object(&self) -> bool {
145 matches!(self, PsbValueFixed::Object(_))
146 }
147
148 pub fn is_string_or_null(&self) -> bool {
150 self.is_string() || self.is_null()
151 }
152
153 pub fn is_string(&self) -> bool {
155 matches!(self, PsbValueFixed::String(_))
156 }
157
158 pub fn is_none(&self) -> bool {
160 matches!(self, PsbValueFixed::None)
161 }
162
163 pub fn is_null(&self) -> bool {
165 matches!(self, PsbValueFixed::Null)
166 }
167
168 pub fn find_resource_key<'a>(
170 &'a self,
171 resource_id: u64,
172 now: Vec<&'a str>,
173 ) -> Option<Vec<&'a str>> {
174 match self {
175 PsbValueFixed::List(l) => l.find_resource_key(resource_id, now),
176 PsbValueFixed::Object(o) => o.find_resource_key(resource_id, now),
177 _ => None,
178 }
179 }
180
181 pub fn find_extra_resource_key<'a>(
183 &'a self,
184 extra_resource_id: u64,
185 now: Vec<&'a str>,
186 ) -> Option<Vec<&'a str>> {
187 match self {
188 PsbValueFixed::List(l) => l.find_extra_resource_key(extra_resource_id, now),
189 PsbValueFixed::Object(o) => o.find_extra_resource_key(extra_resource_id, now),
190 _ => None,
191 }
192 }
193
194 pub fn set_i64(&mut self, value: i64) {
196 *self = PsbValueFixed::Number(PsbNumber::Integer(value));
197 }
198
199 pub fn set_obj(&mut self, value: PsbObjectFixed) {
201 *self = PsbValueFixed::Object(value);
202 }
203
204 pub fn set_str(&mut self, value: &str) {
206 match self {
207 PsbValueFixed::String(s) => {
208 let s = s.string_mut();
209 s.clear();
210 s.push_str(value);
211 }
212 _ => {
213 *self = PsbValueFixed::String(PsbString::from(value.to_owned()));
214 }
215 }
216 }
217
218 pub fn set_string(&mut self, value: String) {
220 self.set_str(&value);
221 }
222
223 pub fn as_u8(&self) -> Option<u8> {
225 self.as_i64().map(|n| n.try_into().ok()).flatten()
226 }
227
228 pub fn as_u32(&self) -> Option<u32> {
230 self.as_i64().map(|n| n as u32)
231 }
232
233 pub fn as_i64(&self) -> Option<i64> {
235 match self {
236 PsbValueFixed::Number(n) => match n {
237 PsbNumber::Integer(n) => Some(*n),
238 _ => None,
239 },
240 _ => None,
241 }
242 }
243
244 pub fn as_str(&self) -> Option<&str> {
246 match self {
247 PsbValueFixed::String(s) => Some(s.string()),
248 _ => None,
249 }
250 }
251
252 pub fn len(&self) -> usize {
254 match self {
255 PsbValueFixed::List(l) => l.len(),
256 PsbValueFixed::Object(o) => o.values.len(),
257 _ => 0,
258 }
259 }
260
261 pub fn entries(&self) -> ObjectIter<'_> {
263 match self {
264 PsbValueFixed::Object(o) => o.iter(),
265 _ => ObjectIter::empty(),
266 }
267 }
268
269 pub fn entries_mut(&mut self) -> ObjectIterMut<'_> {
271 match self {
272 PsbValueFixed::Object(o) => o.iter_mut(),
273 _ => ObjectIterMut::empty(),
274 }
275 }
276
277 pub fn members(&self) -> ListIter<'_> {
279 match self {
280 PsbValueFixed::List(l) => l.iter(),
281 _ => ListIter::empty(),
282 }
283 }
284
285 pub fn members_mut(&mut self) -> ListIterMut<'_> {
287 match self {
288 PsbValueFixed::List(l) => l.iter_mut(),
289 _ => ListIterMut::empty(),
290 }
291 }
292
293 pub fn push_member<T: Into<PsbValueFixed>>(&mut self, value: T) {
295 match self {
296 PsbValueFixed::List(l) => {
297 l.values.push(value.into());
298 }
299 _ => {
300 *self = PsbValueFixed::List(PsbListFixed {
301 values: vec![value.into()],
302 });
303 }
304 }
305 }
306
307 pub fn clear_members(&mut self) {
309 match self {
310 PsbValueFixed::List(l) => {
311 l.clear();
312 }
313 _ => {
314 *self = PsbValueFixed::List(PsbListFixed { values: vec![] });
315 }
316 }
317 }
318
319 pub fn insert_member<T: Into<PsbValueFixed>>(&mut self, index: usize, value: T) {
322 match self {
323 PsbValueFixed::List(l) => {
324 l.insert(index, value);
325 }
326 _ => {
327 *self = PsbValueFixed::List(PsbListFixed {
328 values: vec![value.into()],
329 });
330 }
331 }
332 }
333
334 pub fn resource_id(&self) -> Option<u64> {
336 match self {
337 PsbValueFixed::Resource(r) => Some(r.resource_ref),
338 _ => None,
339 }
340 }
341
342 pub fn extra_resource_id(&self) -> Option<u64> {
344 match self {
345 PsbValueFixed::ExtraResource(er) => Some(er.extra_resource_ref),
346 _ => None,
347 }
348 }
349
350 #[cfg(feature = "json")]
352 pub fn to_json(&self) -> Option<JsonValue> {
353 match self {
354 PsbValueFixed::Null => Some(JsonValue::Null),
355 PsbValueFixed::Bool(b) => Some(JsonValue::Boolean(*b)),
356 PsbValueFixed::Number(n) => match n {
357 PsbNumber::Integer(i) => Some(JsonValue::Number((*i).into())),
358 PsbNumber::Float(f) => Some(JsonValue::Number((*f).into())),
359 PsbNumber::Double(d) => Some(JsonValue::Number((*d).into())),
360 },
361 PsbValueFixed::String(s) => Some(JsonValue::String(s.string().to_owned())),
362 PsbValueFixed::Resource(s) => {
363 Some(JsonValue::String(format!("#resource#{}", s.resource_ref)))
364 }
365 PsbValueFixed::ExtraResource(s) => Some(JsonValue::String(format!(
366 "#resource@{}",
367 s.extra_resource_ref
368 ))),
369 PsbValueFixed::IntArray(arr) => Some(JsonValue::Array(
370 arr.iter().map(|n| JsonValue::Number((*n).into())).collect(),
371 )),
372 PsbValueFixed::List(l) => Some(l.to_json()),
373 PsbValueFixed::Object(o) => Some(o.to_json()),
374 _ => None,
375 }
376 }
377
378 #[cfg(feature = "json")]
380 pub fn from_json(obj: &JsonValue) -> Self {
381 match obj {
382 JsonValue::Null => PsbValueFixed::Null,
383 JsonValue::Boolean(b) => PsbValueFixed::Bool(*b),
384 JsonValue::Number(n) => {
385 let data: f64 = (*n).into();
386 if data.fract() == 0.0 {
387 PsbValueFixed::Number(PsbNumber::Integer(data as i64))
388 } else {
389 PsbValueFixed::Number(PsbNumber::Float(data as f32))
390 }
391 }
392 JsonValue::String(s) => {
393 if s.starts_with("#resource#") {
394 if let Ok(id) = s[10..].parse::<u64>() {
395 return PsbValueFixed::Resource(PsbResourceRef { resource_ref: id });
396 }
397 } else if s.starts_with("#resource@") {
398 if let Ok(id) = s[10..].parse::<u64>() {
399 return PsbValueFixed::ExtraResource(PsbExtraRef {
400 extra_resource_ref: id,
401 });
402 }
403 }
404 PsbValueFixed::String(PsbString::from(s.clone()))
405 }
406 JsonValue::Array(arr) => {
407 let values: Vec<PsbValueFixed> = arr.iter().map(PsbValueFixed::from_json).collect();
408 PsbValueFixed::List(PsbListFixed { values })
409 }
410 JsonValue::Object(obj) => {
411 let mut values = BTreeMap::new();
412 for (key, value) in obj.iter() {
413 values.insert(key.to_owned(), PsbValueFixed::from_json(value));
414 }
415 PsbValueFixed::Object(PsbObjectFixed { values })
416 }
417 JsonValue::Short(n) => {
418 let s = n.as_str();
419 if s.starts_with("#resource#") {
420 if let Ok(id) = s[10..].parse::<u64>() {
421 return PsbValueFixed::Resource(PsbResourceRef { resource_ref: id });
422 }
423 } else if s.starts_with("#resource@") {
424 if let Ok(id) = s[10..].parse::<u64>() {
425 return PsbValueFixed::ExtraResource(PsbExtraRef {
426 extra_resource_ref: id,
427 });
428 }
429 }
430 PsbValueFixed::String(PsbString::from(s.to_owned()))
431 }
432 }
433 }
434}
435
436impl Index<usize> for PsbValueFixed {
437 type Output = PsbValueFixed;
438
439 fn index(&self, index: usize) -> &Self::Output {
440 match self {
441 PsbValueFixed::List(l) => &l[index],
442 _ => &NONE,
443 }
444 }
445}
446
447impl IndexMut<usize> for PsbValueFixed {
448 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
449 match self {
450 PsbValueFixed::List(l) => {
451 if index < l.values.len() {
452 &mut l.values[index]
453 } else {
454 l.values.push(NONE);
455 l.values.last_mut().unwrap()
456 }
457 }
458 _ => {
459 *self = PsbValueFixed::List(PsbListFixed { values: vec![NONE] });
460 self.index_mut(0)
461 }
462 }
463 }
464}
465
466impl<'a> Index<&'a str> for PsbValueFixed {
467 type Output = PsbValueFixed;
468
469 fn index(&self, index: &'a str) -> &Self::Output {
470 match self {
471 PsbValueFixed::Object(o) => &o[index],
472 _ => &NONE,
473 }
474 }
475}
476
477impl<'a> Index<&'a String> for PsbValueFixed {
478 type Output = PsbValueFixed;
479
480 fn index(&self, index: &'a String) -> &Self::Output {
481 self.index(index.as_str())
482 }
483}
484
485impl Index<String> for PsbValueFixed {
486 type Output = PsbValueFixed;
487
488 fn index(&self, index: String) -> &Self::Output {
489 self.index(index.as_str())
490 }
491}
492
493impl IndexMut<&str> for PsbValueFixed {
494 fn index_mut(&mut self, index: &str) -> &mut Self::Output {
495 match self {
496 PsbValueFixed::Object(o) => o.index_mut(index),
497 _ => {
498 *self = PsbValueFixed::Object(PsbObjectFixed {
499 values: BTreeMap::new(),
500 });
501 self.index_mut(index)
502 }
503 }
504 }
505}
506
507impl IndexMut<&String> for PsbValueFixed {
508 fn index_mut(&mut self, index: &String) -> &mut Self::Output {
509 self.index_mut(index.as_str())
510 }
511}
512
513impl IndexMut<String> for PsbValueFixed {
514 fn index_mut(&mut self, index: String) -> &mut Self::Output {
515 self.index_mut(index.as_str())
516 }
517}
518
519impl Clone for PsbValueFixed {
520 fn clone(&self) -> Self {
521 match self {
522 PsbValueFixed::None => PsbValueFixed::None,
523 PsbValueFixed::Null => PsbValueFixed::Null,
524 PsbValueFixed::Bool(b) => PsbValueFixed::Bool(*b),
525 PsbValueFixed::Number(n) => PsbValueFixed::Number(n.clone()),
526 PsbValueFixed::IntArray(arr) => PsbValueFixed::IntArray(arr.clone()),
527 PsbValueFixed::String(s) => PsbValueFixed::String(PsbString::from(s.string().clone())),
528 PsbValueFixed::List(l) => PsbValueFixed::List(l.clone()),
529 PsbValueFixed::Object(o) => PsbValueFixed::Object(o.clone()),
530 PsbValueFixed::Resource(r) => PsbValueFixed::Resource(r.clone()),
531 PsbValueFixed::ExtraResource(er) => PsbValueFixed::ExtraResource(er.clone()),
532 PsbValueFixed::CompilerNumber => PsbValueFixed::CompilerNumber,
533 PsbValueFixed::CompilerString => PsbValueFixed::CompilerString,
534 PsbValueFixed::CompilerResource => PsbValueFixed::CompilerResource,
535 PsbValueFixed::CompilerDecimal => PsbValueFixed::CompilerDecimal,
536 PsbValueFixed::CompilerArray => PsbValueFixed::CompilerArray,
537 PsbValueFixed::CompilerBool => PsbValueFixed::CompilerBool,
538 PsbValueFixed::CompilerBinaryTree => PsbValueFixed::CompilerBinaryTree,
539 }
540 }
541}
542
543impl PartialEq<String> for PsbValueFixed {
544 fn eq(&self, other: &String) -> bool {
545 self == other.as_str()
546 }
547}
548
549impl PartialEq<str> for PsbValueFixed {
550 fn eq(&self, other: &str) -> bool {
551 match self {
552 PsbValueFixed::String(s) => s.string() == other,
553 _ => false,
554 }
555 }
556}
557
558impl<'a> PartialEq<&'a str> for PsbValueFixed {
559 fn eq(&self, other: &&'a str) -> bool {
560 self == *other
561 }
562}
563
564pub trait PsbValueExt {
566 fn to_psb_fixed(self) -> PsbValueFixed;
568}
569
570impl PsbValueExt for PsbValue {
571 fn to_psb_fixed(self) -> PsbValueFixed {
572 match self {
573 PsbValue::None => PsbValueFixed::None,
574 PsbValue::Null => PsbValueFixed::Null,
575 PsbValue::Bool(b) => PsbValueFixed::Bool(b),
576 PsbValue::Number(n) => PsbValueFixed::Number(n),
577 PsbValue::IntArray(arr) => PsbValueFixed::IntArray(arr),
578 PsbValue::String(s) => PsbValueFixed::String(s),
579 PsbValue::List(l) => PsbValueFixed::List(PsbList::to_psb_fixed(l)),
580 PsbValue::Object(o) => PsbValueFixed::Object(PsbObject::to_psb_fixed(o)),
581 PsbValue::Resource(r) => PsbValueFixed::Resource(r),
582 PsbValue::ExtraResource(er) => PsbValueFixed::ExtraResource(er),
583 PsbValue::CompilerNumber => PsbValueFixed::CompilerNumber,
584 PsbValue::CompilerString => PsbValueFixed::CompilerString,
585 PsbValue::CompilerResource => PsbValueFixed::CompilerResource,
586 PsbValue::CompilerDecimal => PsbValueFixed::CompilerDecimal,
587 PsbValue::CompilerArray => PsbValueFixed::CompilerArray,
588 PsbValue::CompilerBool => PsbValueFixed::CompilerBool,
589 PsbValue::CompilerBinaryTree => PsbValueFixed::CompilerBinaryTree,
590 }
591 }
592}
593
594#[derive(Clone, Debug, Serialize, Deserialize)]
595#[serde(transparent)]
596pub struct PsbListFixed {
598 pub values: Vec<PsbValueFixed>,
600}
601
602impl PsbListFixed {
603 pub fn to_psb(self, warn_on_none: bool) -> PsbList {
605 let v: Vec<_> = self
606 .values
607 .into_iter()
608 .map(|v| v.to_psb(warn_on_none))
609 .collect();
610 PsbList::from(v)
611 }
612
613 pub fn find_resource_key<'a>(
615 &'a self,
616 resource_id: u64,
617 now: Vec<&'a str>,
618 ) -> Option<Vec<&'a str>> {
619 for value in &self.values {
620 if let Some(key) = value.find_resource_key(resource_id, now.clone()) {
621 return Some(key);
622 }
623 }
624 None
625 }
626
627 pub fn find_extra_resource_key<'a>(
629 &'a self,
630 extra_resource_id: u64,
631 now: Vec<&'a str>,
632 ) -> Option<Vec<&'a str>> {
633 for value in &self.values {
634 if let Some(key) = value.find_extra_resource_key(extra_resource_id, now.clone()) {
635 return Some(key);
636 }
637 }
638 None
639 }
640
641 pub fn iter(&self) -> ListIter<'_> {
643 ListIter {
644 inner: self.values.iter(),
645 }
646 }
647
648 pub fn iter_mut(&mut self) -> ListIterMut<'_> {
650 ListIterMut {
651 inner: self.values.iter_mut(),
652 }
653 }
654
655 pub fn values(&self) -> &Vec<PsbValueFixed> {
657 &self.values
658 }
659
660 pub fn len(&self) -> usize {
662 self.values.len()
663 }
664
665 pub fn clear(&mut self) {
667 self.values.clear();
668 }
669
670 pub fn insert<V: Into<PsbValueFixed>>(&mut self, index: usize, value: V) {
673 if index <= self.values.len() {
674 self.values.insert(index, value.into());
675 } else {
676 self.values.push(value.into());
677 }
678 }
679
680 #[cfg(feature = "json")]
682 pub fn to_json(&self) -> JsonValue {
683 let data: Vec<_> = self.values.iter().filter_map(|v| v.to_json()).collect();
684 JsonValue::Array(data)
685 }
686}
687
688impl Index<usize> for PsbListFixed {
689 type Output = PsbValueFixed;
690
691 fn index(&self, index: usize) -> &Self::Output {
692 self.values.get(index).unwrap_or(&NONE)
693 }
694}
695
696impl IndexMut<usize> for PsbListFixed {
697 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
698 if index < self.values.len() {
699 &mut self.values[index]
700 } else {
701 self.values.push(NONE);
702 self.values.last_mut().unwrap()
703 }
704 }
705}
706
707pub struct ListIter<'a> {
709 inner: std::slice::Iter<'a, PsbValueFixed>,
710}
711
712impl<'a> ListIter<'a> {
713 pub fn empty() -> Self {
715 ListIter {
716 inner: Default::default(),
717 }
718 }
719}
720
721impl<'a> Iterator for ListIter<'a> {
722 type Item = &'a PsbValueFixed;
723
724 #[inline(always)]
725 fn next(&mut self) -> Option<Self::Item> {
726 self.inner.next()
727 }
728}
729
730impl<'a> ExactSizeIterator for ListIter<'a> {
731 fn len(&self) -> usize {
732 self.inner.len()
733 }
734}
735
736impl<'a> DoubleEndedIterator for ListIter<'a> {
737 #[inline(always)]
738 fn next_back(&mut self) -> Option<Self::Item> {
739 self.inner.next_back()
740 }
741}
742
743pub struct ListIterMut<'a> {
745 inner: std::slice::IterMut<'a, PsbValueFixed>,
746}
747
748impl<'a> ListIterMut<'a> {
749 pub fn empty() -> Self {
751 ListIterMut {
752 inner: Default::default(),
753 }
754 }
755}
756
757impl<'a> Iterator for ListIterMut<'a> {
758 type Item = &'a mut PsbValueFixed;
759
760 #[inline(always)]
761 fn next(&mut self) -> Option<Self::Item> {
762 self.inner.next()
763 }
764}
765
766impl<'a> ExactSizeIterator for ListIterMut<'a> {
767 fn len(&self) -> usize {
768 self.inner.len()
769 }
770}
771
772impl<'a> DoubleEndedIterator for ListIterMut<'a> {
773 #[inline(always)]
774 fn next_back(&mut self) -> Option<Self::Item> {
775 self.inner.next_back()
776 }
777}
778
779pub trait PsbListExt {
781 fn to_psb_fixed(self) -> PsbListFixed;
783}
784
785impl PsbListExt for PsbList {
786 fn to_psb_fixed(self) -> PsbListFixed {
787 let values: Vec<_> = self
788 .unwrap()
789 .into_iter()
790 .map(PsbValue::to_psb_fixed)
791 .collect();
792 PsbListFixed { values }
793 }
794}
795
796#[derive(Clone, Debug, Serialize, Deserialize)]
797#[serde(transparent)]
798pub struct PsbObjectFixed {
800 pub values: BTreeMap<String, PsbValueFixed>,
802}
803
804impl PsbObjectFixed {
805 pub fn new() -> Self {
806 Self {
807 values: BTreeMap::new(),
808 }
809 }
810
811 pub fn to_psb(self, warn_on_none: bool) -> PsbObject {
813 let mut hash_map = HashMap::new();
814 for (key, value) in self.values {
815 hash_map.insert(key, value.to_psb(warn_on_none));
816 }
817 PsbObject::from(hash_map)
818 }
819
820 pub fn get_value(&self, key: &str) -> Option<&PsbValueFixed> {
822 self.values.get(key)
823 }
824
825 pub fn find_resource_key<'a>(
827 &'a self,
828 resource_id: u64,
829 now: Vec<&'a str>,
830 ) -> Option<Vec<&'a str>> {
831 for (key, value) in &self.values {
832 let mut now = now.clone();
833 now.push(key);
834 if let Some(id) = value.resource_id() {
835 if id == resource_id {
836 return Some(now);
837 }
838 }
839 if let Some(key) = value.find_resource_key(resource_id, now) {
840 return Some(key);
841 }
842 }
843 None
844 }
845
846 pub fn find_extra_resource_key<'a>(
848 &'a self,
849 extra_resource_id: u64,
850 now: Vec<&'a str>,
851 ) -> Option<Vec<&'a str>> {
852 for (key, value) in &self.values {
853 let mut now = now.clone();
854 now.push(key);
855 if let Some(id) = value.extra_resource_id() {
856 if id == extra_resource_id {
857 return Some(now);
858 }
859 }
860 if let Some(key) = value.find_extra_resource_key(extra_resource_id, now) {
861 return Some(key);
862 }
863 }
864 None
865 }
866
867 pub fn iter(&self) -> ObjectIter<'_> {
869 ObjectIter {
870 inner: self.values.iter(),
871 }
872 }
873
874 pub fn iter_mut(&mut self) -> ObjectIterMut<'_> {
876 ObjectIterMut {
877 inner: self.values.iter_mut(),
878 }
879 }
880
881 #[cfg(feature = "json")]
883 pub fn to_json(&self) -> JsonValue {
884 let mut obj = json::object::Object::new();
885 for (key, value) in &self.values {
886 if let Some(json_value) = value.to_json() {
887 obj.insert(key, json_value);
888 }
889 }
890 JsonValue::Object(obj)
891 }
892
893 #[cfg(feature = "json")]
895 pub fn from_json(obj: &JsonValue) -> Self {
896 let mut values = BTreeMap::new();
897 for (key, value) in obj.entries() {
898 values.insert(key.to_owned(), PsbValueFixed::from_json(value));
899 }
900 PsbObjectFixed { values }
901 }
902}
903
904impl<'a> Index<&'a str> for PsbObjectFixed {
905 type Output = PsbValueFixed;
906
907 fn index(&self, index: &'a str) -> &Self::Output {
908 self.values.get(index).unwrap_or(&NONE)
909 }
910}
911
912impl<'a> Index<&'a String> for PsbObjectFixed {
913 type Output = PsbValueFixed;
914
915 fn index(&self, index: &'a String) -> &Self::Output {
916 self.index(index.as_str())
917 }
918}
919
920impl Index<String> for PsbObjectFixed {
921 type Output = PsbValueFixed;
922
923 fn index(&self, index: String) -> &Self::Output {
924 self.index(index.as_str())
925 }
926}
927
928impl<'a> IndexMut<&'a str> for PsbObjectFixed {
929 fn index_mut(&mut self, index: &'a str) -> &mut Self::Output {
930 self.values.entry(index.to_string()).or_insert(NONE)
931 }
932}
933
934impl<'a> IndexMut<&'a String> for PsbObjectFixed {
935 fn index_mut(&mut self, index: &'a String) -> &mut Self::Output {
936 self.index_mut(index.as_str())
937 }
938}
939
940impl IndexMut<String> for PsbObjectFixed {
941 fn index_mut(&mut self, index: String) -> &mut Self::Output {
942 self.values.entry(index).or_insert(NONE)
943 }
944}
945
946pub trait PsbObjectExt {
948 fn to_psb_fixed(self) -> PsbObjectFixed;
950}
951
952impl PsbObjectExt for PsbObject {
953 fn to_psb_fixed(self) -> PsbObjectFixed {
954 let mut hash_map = BTreeMap::new();
955 for (key, value) in self.unwrap() {
956 hash_map.insert(key, PsbValue::to_psb_fixed(value));
957 }
958 PsbObjectFixed { values: hash_map }
959 }
960}
961
962pub struct ObjectIter<'a> {
964 inner: std::collections::btree_map::Iter<'a, String, PsbValueFixed>,
965}
966
967impl<'a> ObjectIter<'a> {
968 pub fn empty() -> Self {
970 ObjectIter {
971 inner: Default::default(),
972 }
973 }
974}
975
976impl<'a> Iterator for ObjectIter<'a> {
977 type Item = (&'a String, &'a PsbValueFixed);
978
979 #[inline(always)]
980 fn next(&mut self) -> Option<Self::Item> {
981 self.inner.next()
982 }
983}
984
985impl<'a> ExactSizeIterator for ObjectIter<'a> {
986 fn len(&self) -> usize {
987 self.inner.len()
988 }
989}
990
991impl<'a> DoubleEndedIterator for ObjectIter<'a> {
992 #[inline(always)]
993 fn next_back(&mut self) -> Option<Self::Item> {
994 self.inner.next_back()
995 }
996}
997
998pub struct ObjectIterMut<'a> {
1000 inner: std::collections::btree_map::IterMut<'a, String, PsbValueFixed>,
1001}
1002
1003impl<'a> ObjectIterMut<'a> {
1004 pub fn empty() -> Self {
1006 ObjectIterMut {
1007 inner: Default::default(),
1008 }
1009 }
1010}
1011
1012impl<'a> Iterator for ObjectIterMut<'a> {
1013 type Item = (&'a String, &'a mut PsbValueFixed);
1014
1015 #[inline(always)]
1016 fn next(&mut self) -> Option<Self::Item> {
1017 self.inner.next()
1018 }
1019}
1020
1021impl<'a> ExactSizeIterator for ObjectIterMut<'a> {
1022 fn len(&self) -> usize {
1023 self.inner.len()
1024 }
1025}
1026
1027impl<'a> DoubleEndedIterator for ObjectIterMut<'a> {
1028 #[inline(always)]
1029 fn next_back(&mut self) -> Option<Self::Item> {
1030 self.inner.next_back()
1031 }
1032}
1033
1034#[derive(Clone, Debug)]
1036pub struct VirtualPsbFixed {
1037 header: PsbHeader,
1038 resources: Vec<Vec<u8>>,
1039 extra: Vec<Vec<u8>>,
1040 root: PsbObjectFixed,
1041}
1042
1043impl Serialize for VirtualPsbFixed {
1044 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1045 where
1046 S: serde::Serializer,
1047 {
1048 let mut state = serializer.serialize_struct("VirtualPsbFixed", 3)?;
1049 state.serialize_field("version", &self.header.version)?;
1050 state.serialize_field("encryption", &self.header.encryption)?;
1051 state.serialize_field("data", &self.root)?;
1052 state.end()
1053 }
1054}
1055
1056#[derive(Deserialize)]
1057pub struct VirtualPsbFixedData {
1058 version: u16,
1059 encryption: u16,
1060 data: PsbObjectFixed,
1061}
1062
1063impl VirtualPsbFixed {
1064 pub fn new(
1066 header: PsbHeader,
1067 resources: Vec<Vec<u8>>,
1068 extra: Vec<Vec<u8>>,
1069 root: PsbObjectFixed,
1070 ) -> Self {
1071 Self {
1072 header,
1073 resources,
1074 extra,
1075 root,
1076 }
1077 }
1078
1079 pub fn header(&self) -> PsbHeader {
1081 self.header
1082 }
1083
1084 pub fn resources(&self) -> &Vec<Vec<u8>> {
1086 &self.resources
1087 }
1088
1089 pub fn resources_mut(&mut self) -> &mut Vec<Vec<u8>> {
1091 &mut self.resources
1092 }
1093
1094 pub fn extra(&self) -> &Vec<Vec<u8>> {
1096 &self.extra
1097 }
1098
1099 pub fn extra_mut(&mut self) -> &mut Vec<Vec<u8>> {
1101 &mut self.extra
1102 }
1103
1104 pub fn root(&self) -> &PsbObjectFixed {
1106 &self.root
1107 }
1108
1109 pub fn root_mut(&mut self) -> &mut PsbObjectFixed {
1111 &mut self.root
1112 }
1113
1114 pub fn set_root(&mut self, root: PsbObjectFixed) {
1116 self.root = root;
1117 }
1118
1119 pub fn unwrap(self) -> (PsbHeader, Vec<Vec<u8>>, Vec<Vec<u8>>, PsbObjectFixed) {
1121 (self.header, self.resources, self.extra, self.root)
1122 }
1123
1124 pub fn to_psb(self, warn_on_none: bool) -> VirtualPsb {
1126 let (header, resources, extra, root) = self.unwrap();
1127 VirtualPsb::new(header, resources, extra, root.to_psb(warn_on_none))
1128 }
1129
1130 #[cfg(feature = "json")]
1132 pub fn from_json(&mut self, obj: &JsonValue) -> Result<(), anyhow::Error> {
1133 let version = obj["version"]
1134 .as_u16()
1135 .ok_or_else(|| anyhow::anyhow!("Invalid PSB version"))?;
1136 let encryption = obj["encryption"]
1137 .as_u16()
1138 .ok_or_else(|| anyhow::anyhow!("Invalid PSB encryption"))?;
1139 self.header.version = version;
1140 self.header.encryption = encryption;
1141 self.root = PsbObjectFixed::from_json(&obj["data"]);
1142 Ok(())
1143 }
1144
1145 #[cfg(feature = "json")]
1146 pub fn with_json(obj: &JsonValue) -> Result<Self, anyhow::Error> {
1148 let version = obj["version"]
1149 .as_u16()
1150 .ok_or_else(|| anyhow::anyhow!("Invalid PSB version"))?;
1151 let encryption = obj["encryption"]
1152 .as_u16()
1153 .ok_or_else(|| anyhow::anyhow!("Invalid PSB encryption"))?;
1154 let root = PsbObjectFixed::from_json(&obj["data"]);
1155 Ok(Self {
1156 header: PsbHeader {
1157 version,
1158 encryption,
1159 },
1160 resources: Vec::new(),
1161 extra: Vec::new(),
1162 root,
1163 })
1164 }
1165
1166 pub fn set_data(&mut self, data: VirtualPsbFixedData) {
1167 self.header.version = data.version;
1168 self.header.encryption = data.encryption;
1169 self.root = data.data;
1170 }
1171
1172 #[cfg(feature = "json")]
1174 pub fn to_json(&self) -> JsonValue {
1175 json::object! {
1176 "version": self.header.version,
1177 "encryption": self.header.encryption,
1178 "data": self.root.to_json(),
1179 }
1180 }
1181}
1182
1183pub trait VirtualPsbExt {
1185 fn to_psb_fixed(self) -> VirtualPsbFixed;
1187}
1188
1189impl VirtualPsbExt for VirtualPsb {
1190 fn to_psb_fixed(self) -> VirtualPsbFixed {
1191 let (header, resources, extra, root) = self.unwrap();
1192 VirtualPsbFixed::new(header, resources, extra, root.to_psb_fixed())
1193 }
1194}