vn_core/http/query/
json.rs1use super::FieldSet;
2use crate::error::Result;
3use crate::model::user::UserId;
4use crate::model::{QueryField, SortQueryBy};
5use futures::future::BoxFuture;
6use serde::{Deserialize, Serialize};
7use serde_json::Value as JsonValue;
8use std::borrow::Cow;
9use std::num::NonZeroU16;
10
11type RequestFn<T> = Box<dyn FnOnce(JsonQuery) -> BoxFuture<'static, Result<T>> + Send>;
12
13#[remain::sorted]
14#[derive(Clone, Debug, Default, Deserialize, Serialize)]
15pub struct JsonQuery {
16 compact_filters: bool,
17 count: bool,
18 fields: Option<String>,
19 filters: JsonValue,
20 normalized_filters: bool,
21 page: Option<NonZeroU16>,
22 results: Option<u8>,
23 reverse: bool,
24 sort: Option<String>,
25 user: Option<UserId>,
26}
27
28#[remain::sorted]
29pub struct JsonQueryBuilder<Field, Sort, Value>
30where
31 Field: QueryField,
32 Sort: SortQueryBy,
33 Value: Serialize,
34{
35 compact_filters: bool,
36 count: bool,
37 fields: Option<FieldSet<Field>>,
38 filters: JsonQueryFilter,
39 normalized_filters: bool,
40 page: Option<NonZeroU16>,
41 results: Option<u8>,
42 reverse: bool,
43 send_request: RequestFn<Value>,
44 sort: Option<Sort>,
45 user: Option<UserId>,
46}
47
48impl<Field, Sort, Value> JsonQueryBuilder<Field, Sort, Value>
49where
50 Field: QueryField,
51 Sort: SortQueryBy,
52 Value: Serialize,
53{
54 pub(in crate::http) fn new(send_request: RequestFn<Value>) -> Self {
55 Self {
56 compact_filters: false,
57 count: false,
58 fields: None,
59 filters: JsonQueryFilter::default(),
60 normalized_filters: false,
61 page: None,
62 results: None,
63 reverse: false,
64 send_request,
65 sort: None,
66 user: None,
67 }
68 }
69
70 #[must_use]
71 pub fn compact_filters(mut self) -> Self {
72 self.compact_filters = true;
73 self
74 }
75
76 #[must_use]
77 pub fn count(mut self) -> Self {
78 self.count = true;
79 self
80 }
81
82 #[must_use]
83 pub fn fields(mut self, fields: impl Into<FieldSet<Field>>) -> Self {
84 let fields: FieldSet<Field> = fields.into();
85 if let Some(set) = &mut self.fields {
86 set.inner.extend(fields.inner);
87 } else {
88 self.fields = Some(fields);
89 }
90
91 self
92 }
93
94 #[must_use]
95 pub fn filters(mut self, filter: JsonQueryFilter) -> Self {
96 self.filters = filter;
97 self
98 }
99
100 #[must_use]
101 pub fn normalized_filters(mut self) -> Self {
102 self.normalized_filters = true;
103 self
104 }
105
106 #[must_use]
107 pub fn page(mut self, page: u16) -> Self {
108 self.page = Some(page.try_into().unwrap_or_else(|_| {
109 unsafe { NonZeroU16::new_unchecked(1) }
111 }));
112
113 self
114 }
115
116 #[must_use]
117 pub fn raw_fields<I>(mut self, fields: I) -> Self
118 where
119 I: IntoIterator<Item = String>,
120 {
121 let set = FieldSet::from_raw(fields);
122 if let Some(current) = &mut self.fields {
123 current.inner.extend(set.inner);
124 } else {
125 self.fields = Some(set);
126 }
127
128 self
129 }
130
131 #[must_use]
132 pub fn results(mut self, results: u8) -> Self {
133 self.results = Some(results.min(100));
134 self
135 }
136
137 #[must_use]
138 pub fn reverse(mut self) -> Self {
139 self.reverse = true;
140 self
141 }
142
143 #[must_use]
144 pub fn sort(mut self, sort: Sort) -> Self {
145 self.sort = Some(sort);
146 self
147 }
148
149 #[must_use]
150 pub fn user(mut self, user: impl Into<UserId>) -> Self {
151 self.user = Some(user.into());
152 self
153 }
154
155 pub async fn send(self) -> Result<Value> {
156 let query = JsonQuery {
157 compact_filters: self.compact_filters,
158 count: self.count,
159 fields: self.fields.map(FieldSet::join),
160 filters: self.filters.into_inner(),
161 normalized_filters: self.normalized_filters,
162 page: self.page,
163 results: self.results,
164 reverse: self.reverse,
165 sort: self.sort.map(|s| s.to_string()),
166 user: self.user,
167 };
168
169 (self.send_request)(query).await
170 }
171}
172
173#[derive(Clone, Debug, Deserialize, Serialize)]
174pub struct JsonQueryFilter(JsonValue);
175
176impl JsonQueryFilter {
177 pub fn new(value: JsonValue) -> Self {
178 Self(value)
179 }
180
181 pub fn clear(&mut self) {
182 self.0 = JsonValue::Null;
183 }
184
185 pub fn into_inner(self) -> JsonValue {
186 self.0
187 }
188}
189
190impl Default for JsonQueryFilter {
191 fn default() -> Self {
192 Self(JsonValue::Null)
193 }
194}
195
196impl From<JsonValue> for JsonQueryFilter {
197 fn from(value: JsonValue) -> Self {
198 Self(value)
199 }
200}
201
202impl TryFrom<&str> for JsonQueryFilter {
203 type Error = crate::error::Error;
204
205 fn try_from(value: &str) -> Result<Self> {
206 serde_json::from_str(value)
207 .map(Self)
208 .map_err(Into::into)
209 }
210}
211
212impl TryFrom<String> for JsonQueryFilter {
213 type Error = crate::error::Error;
214
215 fn try_from(value: String) -> Result<Self> {
216 Self::try_from(value.as_str())
217 }
218}
219
220impl TryFrom<&String> for JsonQueryFilter {
221 type Error = crate::error::Error;
222
223 fn try_from(value: &String) -> Result<Self> {
224 Self::try_from(value.as_str())
225 }
226}
227
228impl TryFrom<Cow<'_, str>> for JsonQueryFilter {
229 type Error = crate::error::Error;
230
231 fn try_from(value: Cow<'_, str>) -> Result<Self> {
232 Self::try_from(value.as_ref())
233 }
234}