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