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}