Skip to main content

io_gmail/v1/
query.rs

1//! Turn a `Serialize` struct into URL query pairs.
2//!
3//! A minimal `no_std` serde serializer that flattens a flat struct of
4//! scalars, options and sequences into `(key, value)` string pairs ready
5//! for `url`'s `query_pairs_mut().extend_pairs(...)`. Keys come from the
6//! struct field names (so a `#[serde(rename_all = "camelCase")]` params
7//! struct yields the Gmail query keys for free); `None` and empty
8//! sequences produce nothing, and a sequence produces one repeated-key
9//! pair per element.
10
11use alloc::{
12    string::{String, ToString},
13    vec::Vec,
14};
15use core::fmt;
16
17use serde::{
18    Serialize, Serializer,
19    ser::{Error as SerError, Impossible, SerializeSeq, SerializeStruct},
20};
21
22/// Serialize `value` into a list of URL query `(key, value)` pairs.
23pub fn to_query_pairs<T>(value: &T) -> Vec<(String, String)>
24where
25    T: Serialize + ?Sized,
26{
27    value.serialize(QuerySerializer).unwrap_or_default()
28}
29
30/// Predicate for `#[serde(skip_serializing_if = ...)]` on bool flags that
31/// should only appear in the query when set.
32pub fn is_false(value: &bool) -> bool {
33    !*value
34}
35
36/// Error raised when a value cannot be flattened into query pairs.
37#[derive(Debug)]
38pub struct GmailQueryError(String);
39
40impl fmt::Display for GmailQueryError {
41    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42        f.write_str(&self.0)
43    }
44}
45
46impl core::error::Error for GmailQueryError {}
47
48impl SerError for GmailQueryError {
49    fn custom<T: fmt::Display>(msg: T) -> Self {
50        Self(msg.to_string())
51    }
52}
53
54fn unsupported() -> GmailQueryError {
55    GmailQueryError(String::from(
56        "Query parameters must be a flat struct of scalars and sequences",
57    ))
58}
59
60/// Top-level serializer: only a struct maps to query pairs.
61struct QuerySerializer;
62
63impl Serializer for QuerySerializer {
64    type Ok = Vec<(String, String)>;
65    type Error = GmailQueryError;
66    type SerializeSeq = Impossible<Self::Ok, Self::Error>;
67    type SerializeTuple = Impossible<Self::Ok, Self::Error>;
68    type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
69    type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
70    type SerializeMap = Impossible<Self::Ok, Self::Error>;
71    type SerializeStruct = StructQuery;
72    type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
73
74    fn serialize_struct(
75        self,
76        _name: &'static str,
77        len: usize,
78    ) -> Result<Self::SerializeStruct, Self::Error> {
79        Ok(StructQuery {
80            pairs: Vec::with_capacity(len),
81        })
82    }
83
84    fn serialize_newtype_struct<T>(
85        self,
86        _name: &'static str,
87        value: &T,
88    ) -> Result<Self::Ok, Self::Error>
89    where
90        T: Serialize + ?Sized,
91    {
92        value.serialize(self)
93    }
94
95    fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
96        Err(unsupported())
97    }
98    fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> {
99        Err(unsupported())
100    }
101    fn serialize_i16(self, _: i16) -> Result<Self::Ok, Self::Error> {
102        Err(unsupported())
103    }
104    fn serialize_i32(self, _: i32) -> Result<Self::Ok, Self::Error> {
105        Err(unsupported())
106    }
107    fn serialize_i64(self, _: i64) -> Result<Self::Ok, Self::Error> {
108        Err(unsupported())
109    }
110    fn serialize_u8(self, _: u8) -> Result<Self::Ok, Self::Error> {
111        Err(unsupported())
112    }
113    fn serialize_u16(self, _: u16) -> Result<Self::Ok, Self::Error> {
114        Err(unsupported())
115    }
116    fn serialize_u32(self, _: u32) -> Result<Self::Ok, Self::Error> {
117        Err(unsupported())
118    }
119    fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> {
120        Err(unsupported())
121    }
122    fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
123        Err(unsupported())
124    }
125    fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
126        Err(unsupported())
127    }
128    fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> {
129        Err(unsupported())
130    }
131    fn serialize_str(self, _: &str) -> Result<Self::Ok, Self::Error> {
132        Err(unsupported())
133    }
134    fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok, Self::Error> {
135        Err(unsupported())
136    }
137    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
138        Err(unsupported())
139    }
140    fn serialize_some<T>(self, _: &T) -> Result<Self::Ok, Self::Error>
141    where
142        T: Serialize + ?Sized,
143    {
144        Err(unsupported())
145    }
146    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
147        Err(unsupported())
148    }
149    fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
150        Err(unsupported())
151    }
152    fn serialize_unit_variant(
153        self,
154        _: &'static str,
155        _: u32,
156        _: &'static str,
157    ) -> Result<Self::Ok, Self::Error> {
158        Err(unsupported())
159    }
160    fn serialize_newtype_variant<T>(
161        self,
162        _: &'static str,
163        _: u32,
164        _: &'static str,
165        _: &T,
166    ) -> Result<Self::Ok, Self::Error>
167    where
168        T: Serialize + ?Sized,
169    {
170        Err(unsupported())
171    }
172    fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
173        Err(unsupported())
174    }
175    fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
176        Err(unsupported())
177    }
178    fn serialize_tuple_struct(
179        self,
180        _: &'static str,
181        _: usize,
182    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
183        Err(unsupported())
184    }
185    fn serialize_tuple_variant(
186        self,
187        _: &'static str,
188        _: u32,
189        _: &'static str,
190        _: usize,
191    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
192        Err(unsupported())
193    }
194    fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
195        Err(unsupported())
196    }
197    fn serialize_struct_variant(
198        self,
199        _: &'static str,
200        _: u32,
201        _: &'static str,
202        _: usize,
203    ) -> Result<Self::SerializeStructVariant, Self::Error> {
204        Err(unsupported())
205    }
206}
207
208/// Collects one field at a time into query pairs.
209struct StructQuery {
210    pairs: Vec<(String, String)>,
211}
212
213impl SerializeStruct for StructQuery {
214    type Ok = Vec<(String, String)>;
215    type Error = GmailQueryError;
216
217    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
218    where
219        T: Serialize + ?Sized,
220    {
221        value.serialize(FieldQuery {
222            key,
223            pairs: &mut self.pairs,
224        })
225    }
226
227    fn end(self) -> Result<Self::Ok, Self::Error> {
228        Ok(self.pairs)
229    }
230}
231
232/// Serializes a single field value under a fixed key, pushing one pair
233/// per scalar and one per sequence element (skipping `None`).
234struct FieldQuery<'a> {
235    key: &'static str,
236    pairs: &'a mut Vec<(String, String)>,
237}
238
239impl FieldQuery<'_> {
240    fn push(self, value: String) -> Result<(), GmailQueryError> {
241        self.pairs.push((self.key.to_string(), value));
242        Ok(())
243    }
244}
245
246impl<'a> Serializer for FieldQuery<'a> {
247    type Ok = ();
248    type Error = GmailQueryError;
249    type SerializeSeq = SeqQuery<'a>;
250    type SerializeTuple = Impossible<(), GmailQueryError>;
251    type SerializeTupleStruct = Impossible<(), GmailQueryError>;
252    type SerializeTupleVariant = Impossible<(), GmailQueryError>;
253    type SerializeMap = Impossible<(), GmailQueryError>;
254    type SerializeStruct = Impossible<(), GmailQueryError>;
255    type SerializeStructVariant = Impossible<(), GmailQueryError>;
256
257    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
258        self.push(v.to_string())
259    }
260    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
261        self.push(v.to_string())
262    }
263    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
264        self.push(v.to_string())
265    }
266    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
267        self.push(v.to_string())
268    }
269    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
270        self.push(v.to_string())
271    }
272    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
273        self.push(v.to_string())
274    }
275    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
276        self.push(v.to_string())
277    }
278    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
279        self.push(v.to_string())
280    }
281    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
282        self.push(v.to_string())
283    }
284    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
285        self.push(v.to_string())
286    }
287    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
288        self.push(v.to_string())
289    }
290    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
291        self.push(v.to_string())
292    }
293    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
294        self.push(v.to_string())
295    }
296    fn serialize_unit_variant(
297        self,
298        _: &'static str,
299        _: u32,
300        variant: &'static str,
301    ) -> Result<Self::Ok, Self::Error> {
302        self.push(variant.to_string())
303    }
304    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
305        Ok(())
306    }
307    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
308    where
309        T: Serialize + ?Sized,
310    {
311        value.serialize(self)
312    }
313    fn serialize_newtype_struct<T>(
314        self,
315        _: &'static str,
316        value: &T,
317    ) -> Result<Self::Ok, Self::Error>
318    where
319        T: Serialize + ?Sized,
320    {
321        value.serialize(self)
322    }
323    fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
324        Ok(SeqQuery {
325            key: self.key,
326            pairs: self.pairs,
327        })
328    }
329
330    fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok, Self::Error> {
331        Err(unsupported())
332    }
333    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
334        Err(unsupported())
335    }
336    fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
337        Err(unsupported())
338    }
339    fn serialize_newtype_variant<T>(
340        self,
341        _: &'static str,
342        _: u32,
343        _: &'static str,
344        _: &T,
345    ) -> Result<Self::Ok, Self::Error>
346    where
347        T: Serialize + ?Sized,
348    {
349        Err(unsupported())
350    }
351    fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
352        Err(unsupported())
353    }
354    fn serialize_tuple_struct(
355        self,
356        _: &'static str,
357        _: usize,
358    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
359        Err(unsupported())
360    }
361    fn serialize_tuple_variant(
362        self,
363        _: &'static str,
364        _: u32,
365        _: &'static str,
366        _: usize,
367    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
368        Err(unsupported())
369    }
370    fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
371        Err(unsupported())
372    }
373    fn serialize_struct(
374        self,
375        _: &'static str,
376        _: usize,
377    ) -> Result<Self::SerializeStruct, Self::Error> {
378        Err(unsupported())
379    }
380    fn serialize_struct_variant(
381        self,
382        _: &'static str,
383        _: u32,
384        _: &'static str,
385        _: usize,
386    ) -> Result<Self::SerializeStructVariant, Self::Error> {
387        Err(unsupported())
388    }
389}
390
391/// Serializes each sequence element as a repeated-key pair.
392struct SeqQuery<'a> {
393    key: &'static str,
394    pairs: &'a mut Vec<(String, String)>,
395}
396
397impl SerializeSeq for SeqQuery<'_> {
398    type Ok = ();
399    type Error = GmailQueryError;
400
401    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
402    where
403        T: Serialize + ?Sized,
404    {
405        value.serialize(FieldQuery {
406            key: self.key,
407            pairs: self.pairs,
408        })
409    }
410
411    fn end(self) -> Result<Self::Ok, Self::Error> {
412        Ok(())
413    }
414}