poem_openapi/types/
base64_type.rs

1use std::{
2    borrow::Cow,
3    ops::{Deref, DerefMut},
4};
5
6use base64::engine::{general_purpose::STANDARD, Engine};
7use bytes::Bytes;
8use serde_json::Value;
9
10use crate::{
11    registry::{MetaSchema, MetaSchemaRef},
12    types::{ParseError, ParseFromJSON, ParseFromParameter, ParseResult, ToJSON, Type},
13};
14
15/// Represents a binary data encoded with base64.
16#[derive(Debug, Clone, Eq, PartialEq, Hash)]
17pub struct Base64<T>(pub T);
18
19impl<T> Deref for Base64<T> {
20    type Target = T;
21
22    fn deref(&self) -> &Self::Target {
23        &self.0
24    }
25}
26
27impl<T> DerefMut for Base64<T> {
28    fn deref_mut(&mut self) -> &mut Self::Target {
29        &mut self.0
30    }
31}
32
33impl<T: AsRef<[u8]> + Send + Sync> Type for Base64<T> {
34    const IS_REQUIRED: bool = true;
35
36    type RawValueType = Self;
37
38    type RawElementValueType = Self;
39
40    fn name() -> Cow<'static, str> {
41        "string_bytes".into()
42    }
43
44    fn schema_ref() -> MetaSchemaRef {
45        MetaSchemaRef::Inline(Box::new(MetaSchema::new_with_format("string", "bytes")))
46    }
47
48    fn as_raw_value(&self) -> Option<&Self::RawValueType> {
49        Some(self)
50    }
51
52    fn raw_element_iter<'a>(
53        &'a self,
54    ) -> Box<dyn Iterator<Item = &'a Self::RawElementValueType> + 'a> {
55        Box::new(self.as_raw_value().into_iter())
56    }
57
58    fn is_empty(&self) -> bool {
59        self.0.as_ref().is_empty()
60    }
61}
62
63impl ParseFromJSON for Base64<Vec<u8>> {
64    fn parse_from_json(value: Option<Value>) -> ParseResult<Self> {
65        let value = value.unwrap_or_default();
66        if let Value::String(value) = value {
67            Ok(Self(STANDARD.decode(value)?))
68        } else {
69            Err(ParseError::expected_type(value))
70        }
71    }
72}
73
74impl ParseFromJSON for Base64<Bytes> {
75    fn parse_from_json(value: Option<Value>) -> ParseResult<Self> {
76        let value = value.unwrap_or_default();
77        if let Value::String(value) = value {
78            Ok(Self(STANDARD.decode(value).map(Into::into)?))
79        } else {
80            Err(ParseError::expected_type(value))
81        }
82    }
83}
84
85impl ParseFromParameter for Base64<Vec<u8>> {
86    fn parse_from_parameter(value: &str) -> ParseResult<Self> {
87        Ok(Self(STANDARD.decode(value)?))
88    }
89}
90
91impl ParseFromParameter for Base64<Bytes> {
92    fn parse_from_parameter(value: &str) -> ParseResult<Self> {
93        Ok(Self(STANDARD.decode(value).map(Into::into)?))
94    }
95}
96
97impl<T: AsRef<[u8]> + Send + Sync> ToJSON for Base64<T> {
98    fn to_json(&self) -> Option<Value> {
99        Some(Value::String(STANDARD.encode(self.0.as_ref())))
100    }
101}