pak_db/
group.rs

1use std::{collections::HashSet, marker::PhantomData, sync::Weak};
2use serde::{Deserialize};
3use crate::{Pak, PakInner, error::{PakError, PakResult}, pointer::PakPointer};
4
5//==============================================================================================
6//        DeseerializeUnit
7//==============================================================================================
8
9pub trait DeserializeUnit {
10    type ReturnType;
11    
12     fn deserialize_unit(pak : &Pak, pointer : &PakPointer) -> PakResult<Self::ReturnType>;
13}
14
15impl <T> DeserializeUnit for T where T : for<'de> Deserialize<'de> {
16    type ReturnType = T;
17
18    fn deserialize_unit(pak : &Pak, pointer : &PakPointer) -> PakResult<Self::ReturnType> {
19        pak.read_err::<T>(&pointer)
20    }
21}
22
23//==============================================================================================
24//        PakItemDeserialzedGroup
25//==============================================================================================
26
27pub trait DeserializeGroup {
28    type ReturnType;
29    
30    fn deserialize_group(pak : &Pak, pointers : HashSet<PakPointer>) -> PakResult<Self::ReturnType>;
31    
32    fn get_types() -> Vec<&'static str>;
33}
34
35impl <T> DeserializeGroup for (T, ) where T : DeserializeUnit {
36    type ReturnType = Vec<T::ReturnType>;
37    
38    fn deserialize_group(pak : &Pak, pointers : HashSet<PakPointer>) -> PakResult<Self::ReturnType> {
39        Ok(pointers.iter().filter_map(|pointer| T::deserialize_unit(pak, pointer).ok()).collect::<Vec<_>>())
40    }
41    
42    fn get_types() -> Vec<&'static str> {
43        vec![
44            std::any::type_name::<T>()
45        ]
46    }
47}
48
49macro_rules! impl_group {
50    ( $( $name:ident )+ ) => {
51        impl <$($name,)+> DeserializeGroup for ($($name, )+ ) where $($name : DeserializeUnit, )+ {
52            type ReturnType = ($(Vec<$name::ReturnType>, )+);
53            
54            fn deserialize_group(pak : &Pak, pointers : HashSet<PakPointer>) -> PakResult<Self::ReturnType> {
55                Ok(($(pointers.iter().filter_map(|pointer| $name::deserialize_unit(pak, pointer).ok()).collect::<Vec<_>>(),)+))
56            }
57            
58            fn get_types() -> Vec<&'static str> {
59                vec![$(std::any::type_name::<$name>(), )+]
60            }
61        }
62    };
63}
64
65impl_group!{ A B }
66impl_group!{ A B C }
67impl_group!{ A B C D }
68impl_group!{ A B C D E }
69impl_group!{ A B C D E F }
70impl_group!{ A B C D E F G }
71impl_group!{ A B C D E F G H }
72impl_group!{ A B C D E F G H I }
73impl_group!{ A B C D E F G H I J }
74impl_group!{ A B C D E F G H I J K }
75
76//==============================================================================================
77//        Defer
78//==============================================================================================
79
80/// This is a query result that is defered for later. This is useful when you have a lot of data that you need to load,
81/// but you are okay loading each later.
82pub struct Defer<T> where T : for<'de> Deserialize<'de> {
83    pak : Weak<PakInner>,
84    pointer : PakPointer,
85    data : Option<T>
86}
87
88impl <T> Defer<T> where T : for<'de> Deserialize<'de> {
89    pub fn new(pak : &Pak, pointer : PakPointer) -> Defer<T> {
90        Defer { pak : pak.weak(), pointer, data: None }
91    }
92    
93    pub fn get(&mut self) -> PakResult<&T> {
94        if let None = self.data {
95            let Some(pak) = self.pak.upgrade() else { return Err(PakError::PakDropped) };
96            let value = pak.read_err::<T>(&self.pointer)?;
97            self.data = Some(value);
98        }
99        Ok(self.data.as_ref().unwrap())
100    }
101    
102    pub fn get_mut(&mut self) -> PakResult<&mut T> {
103        if let None = self.data {
104            let Some(pak) = self.pak.upgrade() else { return Err(PakError::PakDropped) };
105            let value = pak.read_err::<T>(&self.pointer)?;
106            self.data = Some(value);
107        }
108        Ok(self.data.as_mut().unwrap())
109    }
110    
111    pub fn peek(&self) -> Option<&T> {
112        self.data.as_ref()
113    }
114    
115    pub fn peek_mut(&mut self) -> Option<&mut T> {
116        self.data.as_mut()
117    }
118    
119    pub fn is_loaded(&self) -> bool {
120        self.data.is_some()
121    }
122}
123
124impl <T> DeserializeUnit for Defer<T> where T : for<'de> Deserialize<'de> {
125    type ReturnType = Defer<T>;
126
127    fn deserialize_unit(pak : &Pak, pointer : &PakPointer) -> PakResult<Self::ReturnType> {
128        Ok(Defer::new(pak, pointer.clone()))
129    }
130}
131
132//==============================================================================================
133//        Pointer
134//==============================================================================================
135
136pub struct Pointer<T>(PhantomData<T>) where T : for <'de> Deserialize<'de>;
137
138impl <T> DeserializeUnit for Pointer<T> where T : for<'de> Deserialize<'de> {
139    type ReturnType = PakPointer;
140
141    fn deserialize_unit(_pak : &Pak, pointer : &PakPointer) -> PakResult<Self::ReturnType> {
142        Ok(pointer.clone())
143    }
144}