pak_db/
pointer.rs

1use serde::{Deserialize, Serialize};
2
3//==============================================================================================
4//        PakPointer
5//==============================================================================================
6
7/// A pointer that points to a specific location in the pak file. It comes in two flavors, typed and untyped. This pointer is typically offset by the size of the header.
8#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Hash)]
9pub enum PakPointer {
10    Typed(PakTypedPointer),
11    Untyped(PakUntypedPointer),
12}
13
14impl PakPointer {
15    pub fn new_typed<T>(offset : u64, size : u64) -> Self {
16        Self::Typed(PakTypedPointer::new(offset, size, std::any::type_name::<T>()))
17    }
18
19    pub fn new_untyped(offset : u64, size : u64) -> Self {
20        Self::Untyped(PakUntypedPointer::new(offset, size))
21    }
22    
23    pub fn offset(&self) -> u64 {
24        match self {
25            Self::Typed(ptr) => ptr.offset,
26            Self::Untyped(ptr) => ptr.offset,
27        }
28    }
29    
30    pub fn size(&self) -> u64 {
31        match self {
32            Self::Typed(ptr) => ptr.size,
33            Self::Untyped(ptr) => ptr.size,
34        }
35    }
36    
37    pub fn type_name(&self) -> &str {
38        match self {
39            Self::Typed(ptr) => &ptr.type_name,
40            Self::Untyped(_) => "Untyped",
41        }
42    }
43    
44    pub fn as_untyped(&self) -> PakUntypedPointer {
45        match self {
46            Self::Typed(ptr) => PakUntypedPointer::new(ptr.offset, ptr.size),
47            Self::Untyped(ptr) => *ptr,
48        }
49    }
50    
51    pub fn into_typed<T>(self) -> PakTypedPointer {
52        match self {
53            Self::Typed(ptr) => ptr,
54            Self::Untyped(ptr) => PakTypedPointer::new(ptr.offset, ptr.size, std::any::type_name::<T>()),
55        }
56    }
57    
58    pub fn type_is_match<T>(&self) -> bool {
59        match self {
60            Self::Typed(ptr) => ptr.type_name == std::any::type_name::<T>(),
61            Self::Untyped(_) => true,
62        }
63    }
64}
65
66impl Clone for PakPointer {
67    fn clone(&self) -> Self {
68        match self {
69            Self::Typed(ptr) => Self::Typed(ptr.clone()),
70            Self::Untyped(ptr) => Self::Untyped(*ptr),
71        }
72    }
73}
74
75//==============================================================================================
76//        PakTypedPointer
77//==============================================================================================
78
79/// A typed pointer. This tells you what rust type is stored at the location pointed to. You can check it with a type at runtime to fail requests that have a type mismatch.
80#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, Hash)]
81pub struct PakTypedPointer {
82    offset : u64,
83    size : u64,
84    type_name : String,
85}
86
87impl PakTypedPointer {
88    pub fn new(offset : u64, size : u64, type_name : &str) -> Self {
89        Self { offset, size, type_name : type_name.to_string() }
90    }
91    
92    pub fn into_pointer(self) -> PakPointer {
93        PakPointer::Typed(self)
94    }
95}
96
97//==============================================================================================
98//        PakUntypedPointer
99//==============================================================================================
100
101/// An untyped pointer. This tells you the offset and size of the data at the location pointed to. This is useful if you always know the type of the data at the location pointed to.
102#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, Serialize, Deserialize, Hash)]
103pub struct PakUntypedPointer {
104    offset : u64,
105    size : u64,
106}
107
108impl PakUntypedPointer {
109    pub fn new(offset : u64, size : u64) -> Self {
110        Self { offset, size }
111    }
112    
113    pub fn as_pointer(&self) -> PakPointer {
114        PakPointer::Untyped(*self)
115    }
116}