From 256d287ba68a83a04ec24f6171a72a64a77f9093 Mon Sep 17 00:00:00 2001 From: Tolmachev Igor Date: Fri, 26 Sep 2025 20:46:02 +0300 Subject: Add Query extractor --- src/error/client.rs | 3 +++ src/error/mod.rs | 8 +++++++- src/extract/mod.rs | 2 ++ src/extract/query.rs | 21 +++++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 src/extract/query.rs diff --git a/src/error/client.rs b/src/error/client.rs index 07d5f97..e93bbb7 100644 --- a/src/error/client.rs +++ b/src/error/client.rs @@ -1,5 +1,6 @@ pub enum ClientError { BadJsonBody(String), + BadQueryString(String), BadAuthTokenHeader(String), UsernameIsTaken { username: String }, InvalidPassword, @@ -13,6 +14,7 @@ impl ClientError { pub fn kind(&self) -> String { match self { Self::BadJsonBody(..) => "BadJsonBody", + Self::BadQueryString(..) => "BadQueryString", Self::BadAuthTokenHeader(..) => "BadAuthTokenHeader", Self::UsernameIsTaken { .. } => "UsernameIsTaken", Self::InvalidPassword => "InvalidPassword", @@ -27,6 +29,7 @@ impl ClientError { pub fn into_message(self) -> String { match self { Self::BadJsonBody(msg) => msg, + Self::BadQueryString(msg) => msg, Self::BadAuthTokenHeader(msg) => msg, Self::UsernameIsTaken { username } => { format!("username `{}` is taken", username) diff --git a/src/error/mod.rs b/src/error/mod.rs index 4b8e1c4..07db26f 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -5,7 +5,7 @@ pub use client::ClientError; pub use server::ServerError; use argon2::password_hash::Error as PasswordHashError; -use axum::extract::rejection::JsonRejection; +use axum::extract::rejection::{JsonRejection, QueryRejection}; use axum_extra::typed_header::TypedHeaderRejection; use sea_orm::DbErr; @@ -34,6 +34,12 @@ impl From for ApiError { } } +impl From for ApiError { + fn from(value: QueryRejection) -> Self { + ClientError::BadJsonBody(value.body_text()).into() + } +} + impl From for ApiError { fn from(value: TypedHeaderRejection) -> Self { ClientError::BadAuthTokenHeader(value.to_string()).into() diff --git a/src/extract/mod.rs b/src/extract/mod.rs index b46a610..e16b9d4 100644 --- a/src/extract/mod.rs +++ b/src/extract/mod.rs @@ -1,5 +1,7 @@ mod auth; mod json; +mod query; pub use auth::Auth; pub use json::ApiJson; +pub use query::ApiQuery; diff --git a/src/extract/query.rs b/src/extract/query.rs new file mode 100644 index 0000000..53c8993 --- /dev/null +++ b/src/extract/query.rs @@ -0,0 +1,21 @@ +use axum::{ + extract::{FromRequestParts, Query, rejection::QueryRejection}, + http::request::Parts, +}; + +use crate::ErrorResponse; + +pub struct ApiQuery(pub T); + +impl FromRequestParts for ApiQuery +where + Query: FromRequestParts, + S: Send + Sync, +{ + type Rejection = ErrorResponse; + + #[inline] + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + Ok(Self(Query::from_request_parts(parts, state).await?.0)) + } +} -- cgit v1.2.3