poem_openapi/types/multipart/
json.rs

1use std::borrow::Cow;
2
3use poem::web::Field as PoemField;
4use serde_json::Value;
5
6use crate::{
7    registry::{MetaSchemaRef, Registry},
8    types::{ParseError, ParseFromJSON, ParseFromMultipartField, ParseResult, ToJSON, Type},
9};
10
11/// A JSON type for multipart field.
12#[derive(Debug, Clone, Eq, PartialEq, Default)]
13pub struct JsonField<T>(pub T);
14
15impl<T: Type> Type for JsonField<T> {
16    const IS_REQUIRED: bool = true;
17
18    type RawValueType = T::RawValueType;
19
20    type RawElementValueType = T::RawElementValueType;
21
22    fn name() -> Cow<'static, str> {
23        T::name()
24    }
25
26    #[inline]
27    fn schema_ref() -> MetaSchemaRef {
28        T::schema_ref()
29    }
30
31    fn register(registry: &mut Registry) {
32        T::register(registry);
33    }
34
35    #[inline]
36    fn as_raw_value(&self) -> Option<&Self::RawValueType> {
37        self.0.as_raw_value()
38    }
39
40    fn raw_element_iter<'a>(
41        &'a self,
42    ) -> Box<dyn Iterator<Item = &'a Self::RawElementValueType> + 'a> {
43        self.0.raw_element_iter()
44    }
45}
46
47impl<T: ParseFromJSON> ParseFromMultipartField for JsonField<T> {
48    async fn parse_from_multipart(field: Option<PoemField>) -> ParseResult<Self> {
49        let value = match field {
50            Some(field) => {
51                let data = field.bytes().await.map_err(ParseError::custom)?;
52                serde_json::from_slice(&data).map_err(ParseError::custom)?
53            }
54            None => Value::Null,
55        };
56        Ok(Self(
57            T::parse_from_json(Some(value)).map_err(ParseError::propagate)?,
58        ))
59    }
60}
61
62impl<T: ToJSON> ToJSON for JsonField<T> {
63    fn to_json(&self) -> Option<Value> {
64        self.0.to_json()
65    }
66}