poem_openapi/types/multipart/
json.rs1use 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#[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}