micro_web/extract/extract_url.rs
1//! URL query string extraction functionality
2//!
3//! This module provides implementation for extracting typed data from URL query strings.
4//! It allows handlers to receive strongly-typed query parameters by implementing the
5//! `FromRequest` trait for the `Query<T>` type.
6//!
7//! # Example
8//! ```no_run
9//! # use serde::Deserialize;
10//! # use micro_web::extract::Query;
11//!
12//! #[derive(Deserialize)]
13//! struct Params {
14//! name: String,
15//! age: u32,
16//! }
17//!
18//! async fn handler(Query(params): Query<Params>) {
19//! println!("Name: {}, Age: {}", params.name, params.age);
20//! }
21//! ```
22
23use crate::extract::Query;
24use crate::extract::from_request::FromRequest;
25use crate::{OptionReqBody, PathParams, RequestContext};
26use micro_http::protocol::ParseError;
27use serde::Deserialize;
28
29/// Implements query string extraction for any type that implements Deserialize
30///
31/// This implementation allows automatic deserialization of query string parameters
32/// into a strongly-typed struct using serde_qs.
33impl<T> FromRequest for Query<T>
34where
35 T: for<'de> Deserialize<'de> + Send,
36{
37 type Output<'r> = T;
38 type Error = ParseError;
39
40 async fn from_request<'r>(req: &'r RequestContext<'_, '_>, _body: OptionReqBody) -> Result<Self::Output<'r>, Self::Error> {
41 let query = req.uri().query().ok_or_else(|| ParseError::invalid_header("has no query string, path"))?;
42 serde_qs::from_str::<'_, T>(query).map_err(|e| ParseError::invalid_header(e.to_string()))
43 }
44}
45
46/// Implements path parameter extraction for referenced PathParams
47///
48/// This implementation is similar to the owned version but works with references
49/// to PathParams. It allows handlers to receive path parameters as references
50/// directly from the request context.
51impl FromRequest for &PathParams<'_, '_> {
52 type Output<'r> = &'r PathParams<'r, 'r>;
53 type Error = ParseError;
54
55 async fn from_request<'r>(req: &'r RequestContext<'_, '_>, _body: OptionReqBody) -> Result<Self::Output<'r>, Self::Error> {
56 Ok(req.path_params())
57 }
58}