1#![doc = include_str!("../../docs/queries.md")]
2
3pub mod pql;
4
5use std::{marker::PhantomData, ops::{BitAnd, BitOr}, rc::Rc, sync::Arc};
6use ordermap::OrderSet;
7
8use crate::{error::PakResult, group::DeserializeGroup, pointer::PakPointer};
9use super::{value::PakValue, Pak};
10
11pub trait PakQueryExpression<T> where T : DeserializeGroup {
16 fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>>;
17}
18
19impl <T> PakQueryExpression<T> for Box<dyn PakQueryExpression<T>> where T : DeserializeGroup {
20 fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
21 self.as_ref().execute(pak)
22 }
23}
24
25impl <T> PakQueryExpression<T> for Rc<dyn PakQueryExpression<T>> where T : DeserializeGroup {
26 fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
27 Rc::as_ref(&self).execute(pak)
28 }
29}
30
31impl <T> PakQueryExpression<T> for Arc<dyn PakQueryExpression<T>> where T : DeserializeGroup {
32 fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
33 Arc::as_ref(&self).execute(pak)
34 }
35}
36
37impl <T, Q> PakQueryExpression<T> for Box<Q> where T : DeserializeGroup, Q : PakQueryExpression<T> {
38 fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
39 self.as_ref().execute(pak)
40 }
41}
42
43impl <T, Q> PakQueryExpression<T> for Rc<Q> where T : DeserializeGroup, Q : PakQueryExpression<T> {
44 fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
45 Rc::as_ref(&self).execute(pak)
46 }
47}
48
49impl <T, Q> PakQueryExpression<T> for Arc<Q> where T : DeserializeGroup, Q : PakQueryExpression<T> {
50 fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
51 Arc::as_ref(&self).execute(pak)
52 }
53}
54
55pub struct PakQueryUnion<T>(Box<dyn PakQueryExpression<T>>, Box<dyn PakQueryExpression<T>>) where T : DeserializeGroup;
60
61impl <T> PakQueryExpression<T> for PakQueryUnion<T> where T : DeserializeGroup {
62 fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
63 let results_a = self.0.execute(pak)?;
64 let results_b = self.1.execute(pak)?;
65 let results = results_a.into_iter().chain(results_b.into_iter()).collect::<OrderSet<_>>();
66 Ok(results)
67 }
68}
69
70impl <T> PakQueryUnion<T> where T : DeserializeGroup {
71 pub fn new(first : impl PakQueryExpression<T> + 'static, second : impl PakQueryExpression<T> + 'static) -> Self {
72 PakQueryUnion(Box::new(first), Box::new(second))
73 }
74}
75
76impl <T, B> BitOr<B> for PakQueryUnion<T> where T : DeserializeGroup + 'static, B : PakQueryExpression<T> + 'static {
77 type Output = Self;
78
79 fn bitor(self, other: B) -> Self::Output {
80 PakQueryUnion(Box::new(self), Box::new(other))
81 }
82}
83
84impl <T, B> BitOr<B> for PakQueryIntersection<T> where T : DeserializeGroup + 'static, B : PakQueryExpression<T> + 'static {
85 type Output = PakQueryUnion<T>;
86
87 fn bitor(self, other: B) -> Self::Output {
88 PakQueryUnion(Box::new(self), Box::new(other))
89 }
90}
91
92impl <T, B> BitOr<B> for PakQuery<T> where T : DeserializeGroup + 'static, B : PakQueryExpression<T> + 'static {
93 type Output = PakQueryUnion<T>;
94
95 fn bitor(self, other: B) -> Self::Output {
96 PakQueryUnion(Box::new(self), Box::new(other))
97 }
98}
99
100pub struct PakQueryIntersection<T>(Box::<dyn PakQueryExpression<T>>, Box::<dyn PakQueryExpression<T>>) where T : DeserializeGroup;
105
106impl <T> PakQueryIntersection<T> where T : DeserializeGroup {
107 pub fn new(first : impl PakQueryExpression<T> + 'static, second : impl PakQueryExpression<T> + 'static) -> Self {
108 PakQueryIntersection(Box::new(first), Box::new(second))
109 }
110}
111
112impl <T> PakQueryExpression<T> for PakQueryIntersection<T> where T : DeserializeGroup {
113 fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
114 let results_a = self.0.execute(pak)?;
115 let results_b = self.1.execute(pak)?;
116 Ok(results_a.into_iter().filter(|e| results_b.contains(e)).collect())
117 }
118}
119
120impl <T, B> BitAnd<B> for PakQuery<T> where T : DeserializeGroup + 'static, B : PakQueryExpression<T> + 'static {
121 type Output = PakQueryIntersection<T>;
122
123 fn bitand(self, rhs: B) -> Self::Output {
124 PakQueryIntersection(Box::new(self), Box::new(rhs))
125 }
126}
127
128impl <T, B> BitAnd<B> for PakQueryUnion<T> where T : DeserializeGroup + 'static, B : PakQueryExpression<T> + 'static {
129 type Output = PakQueryIntersection<T>;
130
131 fn bitand(self, rhs: B) -> Self::Output {
132 PakQueryIntersection(Box::new(self), Box::new(rhs))
133 }
134}
135
136impl <T, B> BitAnd<B> for PakQueryIntersection<T> where T : DeserializeGroup + 'static, B : PakQueryExpression<T> + 'static {
137 type Output = PakQueryIntersection<T>;
138
139 fn bitand(self, rhs: B) -> Self::Output {
140 PakQueryIntersection(Box::new(self), Box::new(rhs))
141 }
142}
143
144
145#[derive(Default)]
150pub enum PakQuery<T : DeserializeGroup> {
151 Equal(String, PakValue, PhantomData<T>),
152 GreaterThan(String, PakValue),
153 LessThan(String, PakValue),
154 GreaterThanEqual(String, PakValue),
155 LessThanEqual(String, PakValue),
156 Contains(String, PakValue),
157 #[default]
158 All
159}
160
161impl <T> PakQuery<T> where T : DeserializeGroup {
162 pub fn equals(key : &str, value : impl Into<PakValue>) -> Self {
163 PakQuery::Equal(key.to_string(), value.into(), PhantomData)
164 }
165
166 pub fn greater_than(key : &str, value : impl Into<PakValue>) -> Self {
167 PakQuery::GreaterThan(key.to_string(), value.into())
168 }
169
170 pub fn less_than(key : &str, value : impl Into<PakValue>) -> Self {
171 PakQuery::LessThan(key.to_string(), value.into())
172 }
173
174 pub fn greater_than_or_equal(key : &str, value : impl Into<PakValue>) -> Self {
175 PakQuery::GreaterThanEqual(key.to_string(), value.into())
176 }
177
178 pub fn less_than_or_equal(key : &str, value : impl Into<PakValue>) -> Self {
179 PakQuery::LessThanEqual(key.to_string(), value.into())
180 }
181
182 pub fn contains(key : &str, value : impl Into<PakValue>) -> Self {
183 PakQuery::Contains(key.to_string(), value.into())
184 }
185}
186
187pub fn equals<T : DeserializeGroup>(key : &str, value : impl Into<PakValue>) -> PakQuery<T> {
188 PakQuery::Equal(key.to_string(), value.into(), PhantomData)
189}
190
191pub fn greater_than<T : DeserializeGroup>(key : &str, value : impl Into<PakValue>) -> PakQuery<T> {
192 PakQuery::GreaterThan(key.to_string(), value.into())
193}
194
195pub fn less_than<T : DeserializeGroup>(key : &str, value : impl Into<PakValue>) -> PakQuery<T> {
196 PakQuery::LessThan(key.to_string(), value.into())
197}
198
199pub fn greater_than_equal<T : DeserializeGroup>(key : &str, value : impl Into<PakValue>) -> PakQuery<T> {
200 PakQuery::GreaterThanEqual(key.to_string(), value.into())
201}
202
203pub fn less_than_equal<T : DeserializeGroup>(key : &str, value : impl Into<PakValue>) -> PakQuery<T> {
204 PakQuery::LessThanEqual(key.to_string(), value.into())
205}
206
207impl <T> PakQueryExpression<T> for PakQuery<T> where T : DeserializeGroup {
208 fn execute(&self, pak : &Pak) -> PakResult<OrderSet<PakPointer>> {
209 match self {
210 PakQuery::Equal(key, pak_value, _) => {
211 let tree = pak.get_tree(key)?;
212 tree.get(pak_value)
213 },
214 PakQuery::GreaterThan(key, pak_value) => {
215 let tree = pak.get_tree(key)?;
216 tree.get_greater(pak_value)
217 },
218 PakQuery::LessThan(key, pak_value) => {
219 let tree = pak.get_tree(key)?;
220 tree.get_less(pak_value)
221 },
222 PakQuery::GreaterThanEqual(key, pak_value) => {
223 let tree = pak.get_tree(key)?;
224 tree.get_greater_eq(pak_value)
225 },
226 PakQuery::LessThanEqual(key, pak_value) => {
227 let tree = pak.get_tree(key)?;
228 tree.get_less_eq(pak_value)
229 },
230 PakQuery::Contains(key, pak_value) => {
231 let tree = pak.get_tree(key)?;
232 tree.get_contains(pak_value)
233 },
234 PakQuery::All => {
235 let list = pak.fetch_all_pointers_of::<T>()?;
236 Ok(list.into_iter().collect::<OrderSet<_>>())
237 }
238 }
239 }
240}