use super::metadata::get_metadata;
use crate::api_description::ApiEndpointBodyContentType;
use crate::api_description::ApiEndpointParameterLocation;
use crate::error::HttpError;
use crate::http_util::http_extract_path_params;
use crate::server::ServerContext;
use crate::ExtractorMetadata;
use crate::RequestContext;
use crate::SharedExtractor;
use async_trait::async_trait;
use schemars::JsonSchema;
use serde::de::DeserializeOwned;
use std::fmt::Debug;
#[derive(Debug)]
pub struct Path<PathType: JsonSchema + Send + Sync> {
inner: PathType,
}
impl<PathType: JsonSchema + Send + Sync> Path<PathType> {
pub fn into_inner(self) -> PathType {
self.inner
}
pub fn map<T, F>(self, f: F) -> Path<T>
where
T: JsonSchema + Send + Sync,
F: FnOnce(PathType) -> T,
{
Path { inner: f(self.inner) }
}
pub fn try_map<T, E, F>(self, f: F) -> Result<Path<T>, E>
where
T: JsonSchema + Send + Sync,
F: FnOnce(PathType) -> Result<T, E>,
{
Ok(Path { inner: f(self.inner)? })
}
}
impl<PathType: JsonSchema + Send + Sync> From<PathType> for Path<PathType> {
fn from(value: PathType) -> Self {
Self { inner: value }
}
}
#[async_trait]
impl<PathType> SharedExtractor for Path<PathType>
where
PathType: DeserializeOwned + JsonSchema + Send + Sync + 'static,
{
async fn from_request<Context: ServerContext>(
rqctx: &RequestContext<Context>,
) -> Result<Path<PathType>, HttpError> {
let params: PathType =
http_extract_path_params(&rqctx.endpoint.variables)?;
Ok(Path { inner: params })
}
fn metadata(
_body_content_type: ApiEndpointBodyContentType,
) -> ExtractorMetadata {
get_metadata::<PathType>(&ApiEndpointParameterLocation::Path)
}
}