poem_openapi/param/
path.rs

1use std::ops::{Deref, DerefMut};
2
3use poem::{Request, RequestBody, Result};
4
5use crate::{
6    error::ParsePathError,
7    registry::{MetaParamIn, MetaSchemaRef, Registry},
8    types::ParseFromParameter,
9    ApiExtractor, ApiExtractorType, ExtractParamOptions,
10};
11
12/// Represents the parameters passed by the URI path.
13pub struct Path<T>(pub T);
14
15impl<T> Deref for Path<T> {
16    type Target = T;
17
18    fn deref(&self) -> &Self::Target {
19        &self.0
20    }
21}
22
23impl<T> DerefMut for Path<T> {
24    fn deref_mut(&mut self) -> &mut Self::Target {
25        &mut self.0
26    }
27}
28
29impl<'a, T: ParseFromParameter> ApiExtractor<'a> for Path<T> {
30    const TYPES: &'static [ApiExtractorType] = &[ApiExtractorType::Parameter];
31    const PARAM_IS_REQUIRED: bool = T::IS_REQUIRED;
32
33    type ParamType = T;
34    type ParamRawType = T::RawValueType;
35
36    fn register(registry: &mut Registry) {
37        T::register(registry);
38    }
39
40    fn param_in() -> Option<MetaParamIn> {
41        Some(MetaParamIn::Path)
42    }
43
44    fn param_schema_ref() -> Option<MetaSchemaRef> {
45        Some(T::schema_ref())
46    }
47
48    fn param_raw_type(&self) -> Option<&Self::ParamRawType> {
49        self.0.as_raw_value()
50    }
51
52    async fn from_request(
53        request: &'a Request,
54        _body: &mut RequestBody,
55        param_opts: ExtractParamOptions<Self::ParamType>,
56    ) -> Result<Self> {
57        let value = match (
58            request.raw_path_param(param_opts.name),
59            &param_opts.default_value,
60        ) {
61            (Some(value), _) => Some(value),
62            (None, Some(default_value)) => return Ok(Self(default_value())),
63            (None, _) => None,
64        };
65
66        ParseFromParameter::parse_from_parameters(value)
67            .map(Self)
68            .map_err(|err| {
69                ParsePathError {
70                    name: param_opts.name,
71                    reason: err.into_message(),
72                }
73                .into()
74            })
75    }
76}