1use base64::Engine;
6use base64::engine::GeneralPurpose;
7use serde::{Deserialize, Deserializer, Serialize, Serializer};
8use serde_with::base64::Base64;
9use serde_with::{DeserializeAs, SerializeAs, formats};
10
11pub(crate) const BASE64_DEFAULT_ENGINE: GeneralPurpose = GeneralPurpose::new(
13 &base64::alphabet::STANDARD,
14 base64::engine::general_purpose::PAD,
15);
16
17pub fn decode_base64_default(value: impl AsRef<[u8]>) -> Result<Vec<u8>, base64::DecodeError> {
19 BASE64_DEFAULT_ENGINE.decode(value)
20}
21
22pub fn encode_base64_default(value: impl AsRef<[u8]>) -> String {
24 BASE64_DEFAULT_ENGINE.encode(value)
25}
26
27pub struct Base64Bcs<Alphabet = serde_with::base64::Standard, Padding = formats::Padded>(
36 std::marker::PhantomData<(Alphabet, Padding)>,
37)
38where
39 Alphabet: serde_with::base64::Alphabet,
40 Padding: formats::Format;
41
42impl<'de, T, Alphabet, Padding> DeserializeAs<'de, T> for Base64Bcs<Alphabet, Padding>
43where
44 Alphabet: serde_with::base64::Alphabet,
45 Padding: formats::Format,
46 T: for<'a> Deserialize<'a>,
47{
48 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
49 where
50 D: Deserializer<'de>,
51 {
52 let bytes: Vec<u8> = Base64::<Alphabet, Padding>::deserialize_as(deserializer)?;
53 bcs::from_bytes(&bytes).map_err(serde::de::Error::custom)
54 }
55}
56
57impl<T, Alphabet> SerializeAs<T> for Base64Bcs<Alphabet, formats::Padded>
58where
59 Alphabet: serde_with::base64::Alphabet,
60 T: Serialize,
61{
62 fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
63 where
64 S: Serializer,
65 {
66 let bytes = bcs::to_bytes(source).map_err(serde::ser::Error::custom)?;
67 Base64::<Alphabet, formats::Padded>::serialize_as(&bytes, serializer)
68 }
69}
70
71impl<T, Alphabet> SerializeAs<T> for Base64Bcs<Alphabet, formats::Unpadded>
72where
73 Alphabet: serde_with::base64::Alphabet,
74 T: Serialize,
75{
76 fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
77 where
78 S: Serializer,
79 {
80 let bytes = bcs::to_bytes(source).map_err(serde::ser::Error::custom)?;
81 Base64::<Alphabet, formats::Unpadded>::serialize_as(&bytes, serializer)
82 }
83}
84
85pub struct Base58;
91
92impl Base58 {
93 pub fn decode(data: impl AsRef<[u8]>) -> Result<Vec<u8>, bs58::decode::Error> {
94 bs58::decode(data).into_vec()
95 }
96
97 pub fn encode(data: impl AsRef<[u8]>) -> String {
98 bs58::encode(data).into_string()
99 }
100}
101
102impl<'de, T> DeserializeAs<'de, T> for Base58
103where
104 T: TryFrom<Vec<u8>>,
105 T::Error: std::fmt::Debug,
106{
107 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
108 where
109 D: Deserializer<'de>,
110 {
111 let s = String::deserialize(deserializer)?;
112 let value = Self::decode(&s).map_err(serde::de::Error::custom)?;
113 let length = value.len();
114 value
115 .try_into()
116 .map_err(|error| serde::de::Error::custom(BytesConversionError { length, error }))
117 }
118}
119
120#[derive(thiserror::Error, Debug)]
121#[error("Converting from a Byte Vector of length {length}: {error:?}")]
122pub struct BytesConversionError<E> {
123 pub length: usize,
124 pub error: E,
125}
126
127impl<T> SerializeAs<T> for Base58
128where
129 T: AsRef<[u8]>,
130{
131 fn serialize_as<S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
132 where
133 S: Serializer,
134 {
135 Self::encode(value).serialize(serializer)
136 }
137}