defuse_serde_utils/
base64.rs1#![allow(rustdoc::broken_intra_doc_links)]
2pub use serde_with::{
4 base64::{Alphabet, Standard, UrlSafe},
5 formats::{Format, Padded, Unpadded},
6};
7
8use derive_more::From;
9use near_sdk::serde::{Deserialize, Deserializer, Serialize, Serializer};
10use serde_with::{DeserializeAs, SerializeAs, serde_as};
11
12pub struct Base64<ALPHABET: Alphabet = Standard, PADDING: Format = Padded>(
13 ::serde_with::base64::Base64<ALPHABET, PADDING>,
14);
15
16impl<T, ALPHABET> SerializeAs<T> for Base64<ALPHABET, Padded>
17where
18 T: AsRef<[u8]>,
19 ALPHABET: Alphabet,
20{
21 fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
22 where
23 S: Serializer,
24 {
25 ::serde_with::base64::Base64::<ALPHABET, Padded>::serialize_as(source, serializer)
26 }
27}
28
29impl<T, ALPHABET> SerializeAs<T> for Base64<ALPHABET, Unpadded>
30where
31 T: AsRef<[u8]>,
32 ALPHABET: Alphabet,
33{
34 fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
35 where
36 S: Serializer,
37 {
38 ::serde_with::base64::Base64::<ALPHABET, Unpadded>::serialize_as(source, serializer)
39 }
40}
41
42impl<'de, T, ALPHABET, FORMAT> DeserializeAs<'de, T> for Base64<ALPHABET, FORMAT>
43where
44 T: TryFrom<Vec<u8>>,
45 ALPHABET: Alphabet,
46 FORMAT: Format,
47{
48 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
49 where
50 D: Deserializer<'de>,
51 {
52 ::serde_with::base64::Base64::<ALPHABET, FORMAT>::deserialize_as(deserializer)
53 }
54}
55
56#[cfg_attr(
59 all(feature = "abi", not(target_arch = "wasm32")),
60 serde_as(schemars = true),
61 derive(::near_sdk::schemars::JsonSchema),
62 schemars(crate = "::near_sdk::schemars", transparent)
63)]
64#[cfg_attr(
65 not(all(feature = "abi", not(target_arch = "wasm32"))),
66 serde_as(schemars = false)
67)]
68#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, From)]
69#[serde(
70 crate = "::near_sdk::serde",
71 bound(serialize = "T: AsRef<[u8]>", deserialize = "T: TryFrom<Vec<u8>>")
72)]
73pub struct AsBase64<T>(#[serde_as(as = "Base64")] pub T);
74
75impl<T> AsBase64<T> {
76 #[inline]
77 pub fn into_inner(self) -> T {
78 self.0
79 }
80}
81
82#[cfg(all(feature = "abi", not(target_arch = "wasm32")))]
83const _: () = {
84 use near_sdk::schemars::{
85 JsonSchema,
86 r#gen::SchemaGenerator,
87 schema::{InstanceType, Schema, SchemaObject},
88 };
89 use serde_with::schemars_0_8::JsonSchemaAs;
90
91 impl<T, ALPHABET, FORMAT> JsonSchemaAs<T> for Base64<ALPHABET, FORMAT>
92 where
93 ALPHABET: Alphabet,
94 FORMAT: Format,
95 {
96 fn schema_name() -> String {
97 String::schema_name()
98 }
99
100 fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
101 SchemaObject {
103 instance_type: Some(InstanceType::String.into()),
104 extensions: [("contentEncoding", "base64".into())]
105 .into_iter()
106 .map(|(k, v)| (k.to_string(), v))
107 .collect(),
108 ..Default::default()
109 }
110 .into()
111 }
112
113 fn is_referenceable() -> bool {
114 false
115 }
116 }
117};