1use ordermap::OrderSet;
2use serde::{Deserialize, Serialize};
3
4use crate::{Pak, error::PakResult, group::{DeserializeGroup}, query::PakQueryExpression};
5
6#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
12pub enum PakPointer {
13 Typed(PakTypedPointer),
14 Untyped(PakUntypedPointer),
15}
16
17impl PakPointer {
18 pub fn new_typed<T>(offset : u64, size : u64) -> Self {
19 Self::Typed(PakTypedPointer::new(offset, size, std::any::type_name::<T>()))
20 }
21
22 pub fn new_untyped(offset : u64, size : u64) -> Self {
23 Self::Untyped(PakUntypedPointer::new(offset, size))
24 }
25
26 pub fn offset(&self) -> u64 {
27 match self {
28 Self::Typed(ptr) => ptr.offset,
29 Self::Untyped(ptr) => ptr.offset,
30 }
31 }
32
33 pub fn size(&self) -> u64 {
34 match self {
35 Self::Typed(ptr) => ptr.size,
36 Self::Untyped(ptr) => ptr.size,
37 }
38 }
39
40 pub fn type_name(&self) -> &str {
41 match self {
42 Self::Typed(ptr) => &ptr.type_name,
43 Self::Untyped(_) => "Untyped",
44 }
45 }
46
47 pub fn as_untyped(&self) -> PakUntypedPointer {
48 match self {
49 Self::Typed(ptr) => PakUntypedPointer::new(ptr.offset, ptr.size),
50 Self::Untyped(ptr) => *ptr,
51 }
52 }
53
54 pub fn into_typed<T>(self) -> PakTypedPointer {
55 match self {
56 Self::Typed(ptr) => ptr,
57 Self::Untyped(ptr) => PakTypedPointer::new(ptr.offset, ptr.size, std::any::type_name::<T>()),
58 }
59 }
60
61 pub fn type_is_match<T>(&self) -> bool {
62 match self {
63 Self::Typed(ptr) => ptr.type_name == std::any::type_name::<T>(),
64 Self::Untyped(_) => true,
65 }
66 }
67
68 pub fn drop_type(&mut self) {
69 let pointer = PakPointer::Untyped(PakUntypedPointer { offset: self.offset(), size: self.size() });
70 *self = pointer
71 }
72}
73
74impl Clone for PakPointer {
75 fn clone(&self) -> Self {
76 match self {
77 Self::Typed(ptr) => Self::Typed(ptr.clone()),
78 Self::Untyped(ptr) => Self::Untyped(*ptr),
79 }
80 }
81}
82
83impl <T> PakQueryExpression<T> for PakPointer where T : DeserializeGroup {
84 fn execute(&self, _pak : &crate::Pak) -> PakResult<OrderSet<PakPointer>> {
85 Ok(OrderSet::from([self.clone()]))
86 }
87}
88
89impl From<PakUntypedPointer> for PakPointer {
90 fn from(value: PakUntypedPointer) -> Self {
91 PakPointer::Untyped(value)
92 }
93}
94
95impl From<PakTypedPointer> for PakPointer {
96 fn from(value: PakTypedPointer) -> Self {
97 PakPointer::Typed(value)
98 }
99}
100
101#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, Hash)]
107pub struct PakTypedPointer {
108 offset : u64,
109 size : u64,
110 type_name : String,
111}
112
113impl PakTypedPointer {
114 pub fn new(offset : u64, size : u64, type_name : &str) -> Self {
115 Self { offset, size, type_name : type_name.to_string() }
116 }
117
118 pub fn into_pointer(self) -> PakPointer {
119 PakPointer::Typed(self)
120 }
121}
122
123#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, Serialize, Deserialize, Hash)]
129pub struct PakUntypedPointer {
130 offset : u64,
131 size : u64,
132}
133
134impl PakUntypedPointer {
135 pub fn new(offset : u64, size : u64) -> Self {
136 Self { offset, size }
137 }
138
139 pub fn as_pointer(&self) -> PakPointer {
140 PakPointer::Untyped(*self)
141 }
142}
143
144pub struct PakCache<T> where T : for<'de> Deserialize<'de> {
149 pointer : PakPointer,
150 cache : Option<T>
151}
152
153impl <T> PakCache<T> where T : for<'de> Deserialize<'de> {
154
155 pub fn fetch(&mut self, pak : &Pak) -> PakResult<&T> {
156 if self.cache.is_some() {
157 Ok(self.cache.as_ref().unwrap())
158 } else {
159 let value = pak.read_err::<T>(&self.pointer)?;
160 self.cache = Some(value);
161 Ok(self.cache.as_ref().unwrap())
162 }
163 }
164
165 pub fn fetch_mut(&mut self, pak : &Pak) -> PakResult<&mut T> {
166 if self.cache.is_some() {
167 Ok(self.cache.as_mut().unwrap())
168 } else {
169 let value = pak.read_err::<T>(&self.pointer)?;
170 self.cache = Some(value);
171 Ok(self.cache.as_mut().unwrap())
172 }
173 }
174
175 pub fn unwrap(self) -> T {
176 self.cache.unwrap()
177 }
178
179 pub fn get(&self) -> Option<&T> {
180 self.cache.as_ref()
181 }
182
183 pub fn get_mut(&mut self) -> Option<&mut T> {
184 self.cache.as_mut()
185 }
186}
187
188impl <T> From<PakPointer> for PakCache<T> where T : for<'de> Deserialize<'de> {
189 fn from(value: PakPointer) -> Self {
190 PakCache { pointer: value, cache: None }
191 }
192}
193
194impl <T> From<PakUntypedPointer> for PakCache<T> where for<'de> T : Deserialize<'de> {
195 fn from(value: PakUntypedPointer) -> Self {
196 let pointer : PakPointer = value.into();
197 pointer.into()
198 }
199}
200
201impl <T> From<PakTypedPointer> for PakCache<T> where for<'de> T : Deserialize<'de> {
202 fn from(value: PakTypedPointer) -> Self {
203 let pointer : PakPointer = value.into();
204 pointer.into()
205 }
206}