defuse_serde_utils/
base58.rs1use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
2use serde_with::{DeserializeAs, SerializeAs};
3
4pub struct Base58;
5
6impl<T> SerializeAs<T> for Base58
7where
8 T: AsRef<[u8]>,
9{
10 fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
11 where
12 S: Serializer,
13 {
14 bs58::encode(source).into_string().serialize(serializer)
15 }
16}
17
18impl<'de, T> DeserializeAs<'de, T> for Base58
19where
20 T: TryFrom<Vec<u8>>,
21{
22 fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
23 where
24 D: Deserializer<'de>,
25 {
26 let s = <&str as Deserialize>::deserialize(deserializer)?;
27
28 let bytes = bs58::decode(s).into_vec().map_err(de::Error::custom)?;
29
30 let length = bytes.len();
31 bytes.try_into().map_err(|_| {
32 de::Error::custom(format_args!(
33 "can't convert a byte vector of length {length} into the output type"
34 ))
35 })
36 }
37}
38
39#[cfg(feature = "abi")]
40const _: () = {
41 use schemars::{
42 JsonSchema,
43 r#gen::SchemaGenerator,
44 schema::{InstanceType, Schema, SchemaObject},
45 };
46 use serde_with::schemars_0_8::JsonSchemaAs;
47
48 impl<T> JsonSchemaAs<T> for Base58 {
49 fn schema_name() -> String {
50 String::schema_name()
51 }
52
53 fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
54 SchemaObject {
56 instance_type: Some(InstanceType::String.into()),
57 extensions: std::iter::once(("contentEncoding", "base58".into()))
58 .map(|(k, v)| (k.to_string(), v))
59 .collect(),
60 ..Default::default()
61 }
62 .into()
63 }
64
65 fn is_referenceable() -> bool {
66 false
67 }
68 }
69};