1extern crate alloc;
3
4use crate::AidokuError;
5use alloc::{
6 format,
7 string::{String, ToString},
8 vec::Vec,
9};
10use core::fmt::Display;
11use paste::paste;
12use serde::{
13 Serialize, Serializer,
14 ser::{Error as SerError, Impossible, SerializeMap, SerializeStruct},
15};
16use thiserror::Error;
17
18pub fn internal_encode_uri<T: AsRef<[u8]>>(url: T, charset: T) -> String {
25 let bytes = url.as_ref();
26 let charset = charset.as_ref();
27 let hex = b"0123456789ABCDEF";
28
29 let mut result: Vec<u8> = Vec::with_capacity(bytes.len() * 3);
30
31 for &byte in bytes {
32 if byte.is_ascii_alphanumeric() || charset.contains(&byte) {
33 result.push(byte);
34 } else {
35 result.push(b'%');
36 result.push(hex[(byte >> 4) as usize]);
37 result.push(hex[(byte & 0x0F) as usize]);
38 }
39 }
40 String::from_utf8(result).unwrap_or_default()
41}
42
43pub fn encode_uri<T: AsRef<[u8]>>(url: T) -> String {
57 internal_encode_uri(url.as_ref(), b";,/?:@&=+$-_.!~*'()#")
58}
59
60pub fn encode_uri_component<T: AsRef<[u8]>>(url: T) -> String {
74 internal_encode_uri(url.as_ref(), b"-_.!~*'()")
75}
76
77pub fn decode_uri<T: AsRef<[u8]>>(encoded: T) -> String {
90 let mut iter = encoded.as_ref().iter();
91 let mut result = Vec::with_capacity(encoded.as_ref().len());
92
93 while let Some(&c) = iter.next() {
94 if c == b'%' {
95 let hi = iter.next();
97 let lo = iter.next();
98 match (hi, lo) {
99 (Some(&hi), Some(&lo)) => {
100 let hex = (hi as char).to_digit(16).zip((lo as char).to_digit(16));
101 match hex {
102 Some((hi, lo)) => result.push(((hi << 4) | lo) as u8),
103 None => {
104 result.push(b'%');
106 result.push(hi);
107 result.push(lo);
108 }
109 }
110 }
111 _ => {
112 result.push(b'%');
114 if let Some(&hi) = hi {
115 result.push(hi);
116 }
117 if let Some(&lo) = lo {
118 result.push(lo);
119 }
120 }
121 }
122 } else {
123 result.push(c);
124 }
125 }
126 String::from_utf8(result).unwrap_or_default()
127}
128
129#[derive(Clone, Debug, Default)]
131pub struct QueryParameters {
132 params: Vec<(String, Option<String>)>,
133}
134
135impl QueryParameters {
136 #[inline]
137 pub fn new() -> Self {
138 QueryParameters { params: Vec::new() }
139 }
140
141 #[inline]
142 pub fn with_capacity(capacity: usize) -> Self {
143 QueryParameters {
144 params: Vec::with_capacity(capacity),
145 }
146 }
147
148 #[inline]
149 pub fn len(&self) -> usize {
150 self.params.len()
151 }
152
153 #[inline]
154 pub fn is_empty(&self) -> bool {
155 self.params.is_empty()
156 }
157
158 pub fn push(&mut self, name: &str, value: Option<&str>) {
161 self.params
162 .push((encode_uri_component(name), value.map(encode_uri_component)));
163 }
164
165 pub fn push_key<K: AsRef<str>>(&mut self, name: K) {
168 self.params
169 .push((encode_uri_component(name.as_ref()), None));
170 }
171
172 pub fn push_encoded(&mut self, name: &str, value: Option<&str>) {
174 self.params
175 .push((name.to_string(), value.map(|v| v.to_string())));
176 }
177
178 pub fn set(&mut self, name: &str, value: Option<&str>) {
181 self.remove_all(name);
182 self.push(name, value);
183 }
184
185 pub fn set_encoded(&mut self, name: &str, value: Option<&str>) {
187 self.remove_all(name);
188 self.push_encoded(name, value);
189 }
190
191 pub fn remove_all<T: AsRef<str>>(&mut self, name: T) {
193 let name = name.as_ref();
194 self.remove_all_encoded(encode_uri_component(name));
195 }
196
197 pub fn remove_all_encoded<T: AsRef<str>>(&mut self, name: T) {
199 let name = name.as_ref();
200 self.params.retain(|(n, _)| n != name);
201 }
202
203 pub fn from_data<T: Serialize>(value: &T) -> Result<Self, SerializeError> {
205 let mut query = Self::new();
206 value.serialize(&mut query)?;
207 Ok(query)
208 }
209}
210
211impl Display for QueryParameters {
212 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
213 let mut first = true;
214 for (n, v) in &self.params {
215 if !first {
216 write!(f, "&")?;
217 } else {
218 first = false;
219 }
220 write!(f, "{}", n)?;
221 if let Some(v) = v {
222 write!(f, "={}", v)?;
223 }
224 }
225 Ok(())
226 }
227}
228
229macro_rules! serialize_integer {
230 ($($type:ty),+) => {$(paste! {
231 fn [<serialize_ $type>](self, v: $type) -> Result<Self::Ok, Self::Error> {
232 self.params
233 .last_mut()
234 .ok_or(SerializeError::TopLevel(stringify!($type)))?
235 .1 = Some(itoa::Buffer::new().format(v).into());
236 Ok(())
237 }
238 })+};
239}
240
241macro_rules! serialize_display {
242 ($($type:ty),+) => {$(paste! {
243 fn [<serialize_ $type>](self, v: $type) -> Result<Self::Ok, Self::Error> {
244 self.params
245 .last_mut()
246 .ok_or(SerializeError::TopLevel(stringify!($type)))?
247 .1 = Some(v.to_string());
248 Ok(())
249 }
250 })+};
251}
252
253impl Serializer for &mut QueryParameters {
254 type Ok = ();
255 type Error = SerializeError;
256
257 type SerializeSeq = Impossible<(), SerializeError>;
258 type SerializeTuple = Impossible<(), SerializeError>;
259 type SerializeTupleStruct = Impossible<(), SerializeError>;
260 type SerializeTupleVariant = Impossible<(), SerializeError>;
261 type SerializeMap = Self;
262 type SerializeStruct = Self;
263 type SerializeStructVariant = Impossible<(), SerializeError>;
264
265 fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
267 self.params.try_last_mut("bool")?.1 = Some(if v { "true" } else { "false" }.into());
268 Ok(())
269 }
270
271 serialize_integer! { i8, i16, i32, i64, i128, u8, u16, u32, u64, u128 }
272
273 serialize_display! { f32, f64 }
274
275 fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
277 if self.params.last().is_none() {
278 return Err(SerializeError::TopLevel("char"));
279 }
280
281 let mut b = [0; 4];
282 self.serialize_str(v.encode_utf8(&mut b))
283 }
284
285 fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
287 if self.params.last().is_none() {
288 return Err(SerializeError::TopLevel("&str"));
289 }
290
291 self.serialize_bytes(v.as_bytes())
292 }
293
294 fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
295 self.params.try_last_mut("&[u8]")?.1 = Some(encode_uri_component(v));
296 Ok(())
297 }
298
299 fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
301 let last = self.params.try_last_mut("Option<T>")?;
302 if last.0.is_empty() {
303 return Err(SerializeError::InvalidKey("Option<T>"));
304 }
305
306 last.1 = None;
307 Ok(())
308 }
309
310 fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
311 where
312 T: ?Sized + Serialize,
313 {
314 if self
315 .params
316 .last()
317 .ok_or(SerializeError::TopLevel("Option<T>"))?
318 .0
319 .is_empty()
320 {
321 return Err(SerializeError::InvalidKey("Option<T>"));
322 }
323
324 value.serialize(self)
325 }
326
327 fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
329 self.params.try_last_mut("()")?.1 = Some(String::new());
330 Ok(())
331 }
332
333 fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
335 if self.params.last().is_none() {
336 return Err(SerializeError::TopLevel(name));
337 }
338
339 self.serialize_unit()
340 }
341
342 fn serialize_unit_variant(
344 self,
345 name: &'static str,
346 _variant_index: u32,
347 variant: &'static str,
348 ) -> Result<Self::Ok, Self::Error> {
349 if self.params.last().is_none() {
350 return Err(SerializeError::TopLevel(name));
351 }
352
353 self.serialize_str(variant)
354 }
355
356 fn serialize_newtype_struct<T>(
358 self,
359 name: &'static str,
360 value: &T,
361 ) -> Result<Self::Ok, Self::Error>
362 where
363 T: ?Sized + Serialize,
364 {
365 if self.params.last().is_none() {
366 return Err(SerializeError::TopLevel(name));
367 }
368
369 value.serialize(self)
370 }
371
372 fn serialize_newtype_variant<T>(
374 self,
375 name: &'static str,
376 _variant_index: u32,
377 _variant: &'static str,
378 value: &T,
379 ) -> Result<Self::Ok, Self::Error>
380 where
381 T: ?Sized + Serialize,
382 {
383 if self.params.last().is_none() {
384 return Err(SerializeError::TopLevel(name));
385 }
386
387 value.serialize(self)
388 }
389
390 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
391 Err(SerializeError::invalid("Vec<T>"))
392 }
393
394 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
395 Err(SerializeError::invalid("(T0, T1,...)` or `[T, T,...]"))
396 }
397
398 fn serialize_tuple_struct(
399 self,
400 name: &'static str,
401 _len: usize,
402 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
403 Err(SerializeError::invalid(name))
404 }
405
406 fn serialize_tuple_variant(
407 self,
408 name: &'static str,
409 _variant_index: u32,
410 variant: &'static str,
411 _len: usize,
412 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
413 Err(SerializeError::invalid(format!("{name}::{variant}")))
414 }
415
416 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
417 if len.is_some() && !self.params.is_empty() {
418 return Err(SerializeError::NotTopLevel("Map<K, V>"));
419 }
420
421 Ok(self)
422 }
423
424 fn serialize_struct(
425 self,
426 name: &'static str,
427 _len: usize,
428 ) -> Result<Self::SerializeStruct, Self::Error> {
429 if !self.params.is_empty() {
430 return Err(SerializeError::NotTopLevel(name));
431 }
432
433 Ok(self)
434 }
435
436 fn serialize_struct_variant(
437 self,
438 name: &'static str,
439 _variant_index: u32,
440 variant: &'static str,
441 _len: usize,
442 ) -> Result<Self::SerializeStructVariant, Self::Error> {
443 Err(SerializeError::invalid(format!("{name}::{variant}")))
444 }
445}
446
447impl SerializeMap for &mut QueryParameters {
448 type Ok = ();
449 type Error = SerializeError;
450
451 fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
452 where
453 T: ?Sized + Serialize,
454 {
455 self.push_encoded("", None);
456 key.serialize(&mut **self)?;
457 let last = self.params.last_mut().ok_or(SerializeError::NoParam)?;
458 last.0 = last
459 .1
460 .as_deref()
461 .ok_or(SerializeError::InvalidKey("Option<T>"))?
462 .into();
463 Ok(())
464 }
465
466 fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
467 where
468 T: ?Sized + Serialize,
469 {
470 value.serialize(&mut **self)
471 }
472
473 fn end(self) -> Result<Self::Ok, Self::Error> {
474 Ok(())
475 }
476}
477
478impl SerializeStruct for &mut QueryParameters {
479 type Ok = ();
480 type Error = SerializeError;
481
482 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
483 where
484 T: ?Sized + Serialize,
485 {
486 self.push_key(key);
487 value.serialize(&mut **self)
488 }
489
490 fn end(self) -> Result<Self::Ok, Self::Error> {
491 Ok(())
492 }
493}
494
495#[derive(Error, Debug, PartialEq, Eq)]
496pub enum SerializeError {
497 #[error("{0}")]
498 Custom(String),
499 #[error("`{0}` can only be serialized at the top level")]
500 NotTopLevel(&'static str),
501 #[error("cannot serialize `{0}` at the top level")]
502 TopLevel(&'static str),
503 #[error("expected parameter after serialized key, but none was found")]
504 NoParam,
505 #[error("cannot serialize `{0}` as key")]
506 InvalidKey(&'static str),
507 #[error("cannot serialize `{0}`")]
508 Invalid(String),
509}
510
511impl SerializeError {
512 fn invalid<S: Display>(r#type: S) -> Self {
513 Self::Invalid(r#type.to_string())
514 }
515}
516
517impl From<SerializeError> for AidokuError {
518 fn from(error: SerializeError) -> Self {
519 Self::Message(error.to_string())
520 }
521}
522
523impl SerError for SerializeError {
524 fn custom<T>(msg: T) -> Self
525 where
526 T: Display,
527 {
528 Self::Custom(msg.to_string())
529 }
530}
531
532trait TryParams {
533 type Param;
534 fn try_last_mut(&mut self, r#type: &'static str) -> Result<&mut Self::Param, SerializeError>;
535}
536
537impl<T> TryParams for Vec<T> {
538 type Param = T;
539 fn try_last_mut(&mut self, r#type: &'static str) -> Result<&mut Self::Param, SerializeError> {
540 self.last_mut().ok_or(SerializeError::TopLevel(r#type))
541 }
542}