logo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#[macro_export]
/// This macro implements ApiExtractor for your type, with additional bounds
/// if you want to.
macro_rules! impl_apirequest_for_payload {
    ($ty:ty) => {
        impl_apirequest_for_payload!($ty,);
    };

    ($ty:ty, $($bounds:tt)*) => {
        #[poem::async_trait]
        impl<'a, $($bounds)*> $crate::ApiExtractor<'a> for $ty {
            const TYPE: $crate::ApiExtractorType = $crate::ApiExtractorType::RequestObject;

            type ParamType = ();
            type ParamRawType = ();

            fn register(registry: &mut $crate::registry::Registry) {
                <Self as $crate::payload::Payload>::register(registry);
            }

            fn request_meta() -> Option<$crate::registry::MetaRequest> {
                Some($crate::registry::MetaRequest {
                    description: None,
                    content: vec![$crate::registry::MetaMediaType {
                        content_type: <Self as $crate::payload::Payload>::CONTENT_TYPE,
                        schema: <Self as $crate::payload::Payload>::schema_ref(),
                    }],
                    required: <Self as $crate::payload::ParsePayload>::IS_REQUIRED,
                })
            }

            async fn from_request(
                request: &'a poem::Request,
                body: &mut poem::RequestBody,
                _param_opts: $crate::ExtractParamOptions<Self::ParamType>,
            ) -> poem::Result<Self> {
                match request.content_type() {
                    Some(content_type) => {
                        let mime: mime::Mime = match content_type.parse() {
                            Ok(mime) => mime,
                            Err(_) => {
                                return Err($crate::error::ContentTypeError::NotSupported {
                                    content_type: content_type.to_string(),
                                }.into());
                            }
                        };

                        if mime.essence_str() != <Self as $crate::payload::Payload>::CONTENT_TYPE {
                            return Err($crate::error::ContentTypeError::NotSupported {
                                content_type: content_type.to_string(),
                            }.into());
                        }

                        <Self as $crate::payload::ParsePayload>::from_request(request, body).await
                    }
                    None => Err($crate::error::ContentTypeError::ExpectContentType.into()),
                }
            }
        }
    };
}