1use ordermap::OrderSet;
2use serde::{Deserialize, Serialize};
3
4use crate::{error::PakResult, 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
69impl Clone for PakPointer {
70 fn clone(&self) -> Self {
71 match self {
72 Self::Typed(ptr) => Self::Typed(ptr.clone()),
73 Self::Untyped(ptr) => Self::Untyped(*ptr),
74 }
75 }
76}
77
78impl PakQueryExpression for PakPointer {
79 fn execute(&self, _pak : &crate::Pak) -> PakResult<OrderSet<PakPointer>> {
80 Ok(OrderSet::from([self.clone()]))
81 }
82}
83
84#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, Hash)]
90pub struct PakTypedPointer {
91 offset : u64,
92 size : u64,
93 type_name : String,
94}
95
96impl PakTypedPointer {
97 pub fn new(offset : u64, size : u64, type_name : &str) -> Self {
98 Self { offset, size, type_name : type_name.to_string() }
99 }
100
101 pub fn into_pointer(self) -> PakPointer {
102 PakPointer::Typed(self)
103 }
104}
105
106#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, Serialize, Deserialize, Hash)]
112pub struct PakUntypedPointer {
113 offset : u64,
114 size : u64,
115}
116
117impl PakUntypedPointer {
118 pub fn new(offset : u64, size : u64) -> Self {
119 Self { offset, size }
120 }
121
122 pub fn as_pointer(&self) -> PakPointer {
123 PakPointer::Untyped(*self)
124 }
125}