1use queryst::parse;
2use std::collections::HashMap;
3use serde_json::value::Value;
4
5#[derive(Debug, PartialEq, Clone, Copy)]
6pub struct PageParams {
7 pub size: i64,
8 pub number: i64,
9}
10
11#[derive(Clone, Debug, PartialEq, Default)]
13pub struct Query {
14 pub _type: String,
15 pub include: Option<Vec<String>>,
16 pub fields: Option<HashMap<String, Vec<String>>>,
17 pub page: Option<PageParams>,
18 pub sort: Option<Vec<String>>,
19 pub filter: Option<HashMap<String, Vec<String>>>
20}
21
22fn ok_params_include(o:&Value) -> Option<Vec<String>> {
27 match o.pointer("/include") {
28 None => None,
29 Some(inc) => {
30 match inc.as_str() {
31 None => None,
32 Some(include_str) => {
33 let arr: Vec<String> =
34 include_str.split(',').map(|s| s.to_string()).collect();
35 Some(arr)
36 }
37 }
38 }
39 }
40}
41
42fn ok_params_fields(o:&Value) -> HashMap<String, Vec<String>> {
43 let mut fields = HashMap::<String, Vec<String>>::new();
44
45 if let Some(x) = o.pointer("/fields") {
46 if x.is_object() {
47 if let Some(obj) = x.as_object() {
48 for (key, value) in obj.iter() {
49 let arr: Vec<String> = match value.as_str() {
50 Some(string) => {
51 string.split(',').map(|s| s.to_string()).collect()
52 }
53 None => Vec::<String>::new(),
54 };
55 fields.insert(key.to_string(), arr);
56
57 }
58 }
59 } else {
60 warn!("Query::from_params : No fields found in {:?}", x);
61 }
62 }
63
64 fields
65}
66
67fn ok_params_sort(o:&Value) -> Option<Vec<String>> {
68 match o.pointer("/sort") {
69 None => None,
70 Some(sort) => {
71 match sort.as_str() {
72 None => None,
73 Some(sort_str) => {
74 let arr: Vec<String> =
75 sort_str.split(',').map(|s| s.to_string()).collect();
76 Some(arr)
77 }
78 }
79 }
80 }
81}
82
83fn ok_params_filter(o:&Value) -> Option<HashMap<String, Vec<String>>> {
84 match o.pointer("/filter") {
85 None => None,
86 Some(x) => {
87 if x.is_object() {
88 let mut tmp_filter = HashMap::<String, Vec<String>>::new();
89 if let Some(obj) = x.as_object() {
90 for (key, value) in obj.iter() {
91 let arr: Vec<String> = match value.as_str() {
92 Some(string) => {
93 string.split(',').map(|s| s.to_string()).collect()
94 }
95 None => Vec::<String>::new(),
96 };
97 tmp_filter.insert(key.to_string(), arr);
98 }
99 }
100 Some(tmp_filter)
101 } else {
102 warn!("Query::from_params : No filter found in {:?}", x);
103 None
104 }
105 }
106 }
107}
108
109fn ok_params_page(o:&Value) -> PageParams {
110 PageParams {
111 number: match o.pointer("/page/number") {
112 None => {
113 warn!(
114 "Query::from_params : No page/number found in {:?}, setting \
115 default 0",
116 o
117 );
118 0
119 }
120 Some(num) => {
121 if num.is_string() {
122 match num.as_str().map(str::parse::<i64>) {
123 Some(y) => y.unwrap_or(0),
124 None => {
125 warn!(
126 "Query::from_params : page/number found in {:?}, \
127 not able not able to parse it - setting default 0",
128 o
129 );
130 0
131 }
132 }
133 } else {
134 warn!(
135 "Query::from_params : page/number found in {:?}, but it is \
136 not an expected type - setting default 0",
137 o
138 );
139 0
140 }
141 }
142 },
143 size: match o.pointer("/page/size") {
144 None => {
145 warn!(
146 "Query::from_params : No page/size found in {:?}, setting \
147 default 0",
148 o
149 );
150 0
151 }
152 Some(num) => {
153 if num.is_string() {
154 match num.as_str().map(str::parse::<i64>) {
155 Some(y) => y.unwrap_or(0),
156 None => {
157 warn!(
158 "Query::from_params : page/size found in {:?}, \
159 not able not able to parse it - setting default 0",
160 o
161 );
162 0
163 }
164 }
165 } else {
166 warn!(
167 "Query::from_params : page/size found in {:?}, but it is \
168 not an expected type - setting default 0",
169 o
170 );
171 0
172 }
173 }
174 },
175 }
176}
177
178fn ok_params(o:Value) -> Query {
179 Query {
180 _type: "none".into(),
181 include : ok_params_include(&o),
182 fields: Some(ok_params_fields(&o)),
183 page: Some(ok_params_page(&o)),
184 sort: ok_params_sort(&o),
185 filter: ok_params_filter(&o),
186 }
187}
188
189impl Query {
191 pub fn from_params(params: &str) -> Self {
208
209 match parse(params) {
210 Ok(o) => {
211 ok_params(o)
212 }
213 Err(err) => {
214 warn!("Query::from_params : Can't parse : {:?}", err);
215 Query {
216 _type: "none".into(),
217 ..Default::default()
218 }
219 }
220 }
221 }
222
223 pub fn to_params(&self) -> String {
245 let mut params = Vec::<String>::new();
246
247 if let Some(ref include) = self.include {
248 params.push(format!("include={}", include.join(",")));
249 }
250
251 if let Some(ref fields) = self.fields {
256 for (name, val) in fields.iter() {
257 params.push(format!("fields[{}]={}", name, val.join(",")));
258 }
259 }
260
261 if let Some(ref sort) = self.sort {
262 params.push(format!("sort={}", sort.join(",")))
263 }
264
265 if let Some(ref filter) = self.filter {
266 for (name, val) in filter.iter() {
267 params.push(format!("filter[{}]={}", name, val.join(",")));
268 }
269 }
270
271 if let Some(ref page) = self.page {
272 params.push(page.to_params());
273 }
274
275 params.join("&")
276 }
277}
278
279impl PageParams {
280 pub fn to_params(&self) -> String {
281 format!("page[size]={}&page[number]={}", self.size, self.number)
282 }
283}