1use ordermap::OrderSet;
2use serde::{Deserialize, Serialize};
3
4use crate::{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}