use super::openapi::ParameterIn as ParameterLocation;
use super::{Parameter, Required};
use crate::ToSchema;
use std::marker::PhantomData;
pub trait ParameterMetadata {
fn parameter_metadata(name: &str, include_in_schema: bool) -> Option<Parameter>;
}
pub struct PathParam<T>(PhantomData<T>);
pub struct QueryParam<T>(PhantomData<T>);
pub struct HeaderParam<T>(PhantomData<T>);
pub struct CookieParam<T>(PhantomData<T>);
impl<T: ToSchema> ParameterMetadata for PathParam<T> {
fn parameter_metadata(name: &str, include_in_schema: bool) -> Option<Parameter> {
if !include_in_schema {
return None;
}
use utoipa::openapi::path::ParameterBuilder;
Some(
ParameterBuilder::new()
.name(name)
.parameter_in(ParameterLocation::Path)
.required(Required::True) .schema(Some(T::schema()))
.build(),
)
}
}
impl<T: ToSchema> ParameterMetadata for QueryParam<T> {
fn parameter_metadata(name: &str, include_in_schema: bool) -> Option<Parameter> {
if !include_in_schema {
return None;
}
use utoipa::openapi::path::ParameterBuilder;
Some(
ParameterBuilder::new()
.name(name)
.parameter_in(ParameterLocation::Query)
.required(Required::False) .schema(Some(T::schema()))
.build(),
)
}
}
impl<T: ToSchema> ParameterMetadata for HeaderParam<T> {
fn parameter_metadata(name: &str, include_in_schema: bool) -> Option<Parameter> {
if !include_in_schema {
return None;
}
use utoipa::openapi::path::ParameterBuilder;
Some(
ParameterBuilder::new()
.name(name)
.parameter_in(ParameterLocation::Header)
.required(Required::False) .schema(Some(T::schema()))
.build(),
)
}
}
impl<T: ToSchema> ParameterMetadata for CookieParam<T> {
fn parameter_metadata(name: &str, include_in_schema: bool) -> Option<Parameter> {
if !include_in_schema {
return None;
}
use utoipa::openapi::path::ParameterBuilder;
Some(
ParameterBuilder::new()
.name(name)
.parameter_in(ParameterLocation::Cookie)
.required(Required::False) .schema(Some(T::schema()))
.build(),
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_path_parameter_metadata() {
let param = PathParam::<i64>::parameter_metadata("id", true);
let param = param.unwrap();
assert_eq!(param.name, "id");
assert!(matches!(param.parameter_in, ParameterLocation::Path));
assert!(matches!(param.required, Required::True));
assert!(param.schema.is_some());
}
#[test]
fn test_path_parameter_hidden() {
let param = PathParam::<i64>::parameter_metadata("id", false);
assert!(param.is_none(), "Hidden parameter should return None");
}
#[test]
fn test_query_parameter_metadata() {
let param = QueryParam::<String>::parameter_metadata("search", true);
let param = param.unwrap();
assert_eq!(param.name, "search");
assert!(matches!(param.parameter_in, ParameterLocation::Query));
assert!(matches!(param.required, Required::False));
}
#[test]
fn test_query_parameter_hidden() {
let param = QueryParam::<String>::parameter_metadata("search", false);
assert!(param.is_none());
}
#[test]
fn test_header_parameter_metadata() {
let param = HeaderParam::<String>::parameter_metadata("X-API-Key", true);
let param = param.unwrap();
assert_eq!(param.name, "X-API-Key");
assert!(matches!(param.parameter_in, ParameterLocation::Header));
assert!(matches!(param.required, Required::False));
}
#[test]
fn test_header_parameter_hidden() {
let param = HeaderParam::<String>::parameter_metadata("X-API-Key", false);
assert!(param.is_none());
}
#[test]
fn test_cookie_parameter_metadata() {
let param = CookieParam::<String>::parameter_metadata("session_id", true);
let param = param.unwrap();
assert_eq!(param.name, "session_id");
assert!(matches!(param.parameter_in, ParameterLocation::Cookie));
assert!(matches!(param.required, Required::False));
}
#[test]
fn test_cookie_parameter_hidden() {
let param = CookieParam::<String>::parameter_metadata("session_id", false);
assert!(param.is_none());
}
#[test]
fn test_multiple_parameter_types() {
let path_int = PathParam::<i64>::parameter_metadata("id", true).unwrap();
let path_str = PathParam::<String>::parameter_metadata("slug", true).unwrap();
let query_bool = QueryParam::<bool>::parameter_metadata("active", true).unwrap();
assert!(path_int.schema.is_some());
assert!(path_str.schema.is_some());
assert!(query_bool.schema.is_some());
}
}