defuse_serde_utils/
base58.rs

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