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