defuse_crypto/
serde.rs

1use core::marker::PhantomData;
2
3use near_sdk::{
4    serde::{Deserialize, Deserializer, Serialize, Serializer, de},
5    serde_with::{DeserializeAs, SerializeAs},
6};
7
8use crate::TypedCurve;
9
10pub struct AsCurve<C: TypedCurve>(PhantomData<C>);
11
12impl<C: TypedCurve, const N: usize> SerializeAs<[u8; N]> for AsCurve<C> {
13    fn serialize_as<S>(source: &[u8; N], serializer: S) -> Result<S::Ok, S::Error>
14    where
15        S: Serializer,
16    {
17        C::to_base58(source).serialize(serializer)
18    }
19}
20
21impl<'de, C: TypedCurve, const N: usize> DeserializeAs<'de, [u8; N]> for AsCurve<C> {
22    fn deserialize_as<D>(deserializer: D) -> Result<[u8; N], D::Error>
23    where
24        D: Deserializer<'de>,
25    {
26        let s = <&str as Deserialize>::deserialize(deserializer)?;
27        C::parse_base58(s).map_err(de::Error::custom)
28    }
29}
30
31#[cfg(feature = "abi")]
32const _: () = {
33    use near_sdk::{
34        schemars::{
35            JsonSchema,
36            r#gen::SchemaGenerator,
37            schema::{InstanceType, Schema, SchemaObject, StringValidation},
38        },
39        serde_with::schemars_0_8::JsonSchemaAs,
40    };
41
42    impl<C: TypedCurve, const N: usize> JsonSchemaAs<[u8; N]> for AsCurve<C> {
43        fn schema_name() -> String {
44            String::schema_name()
45        }
46
47        fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
48            SchemaObject {
49                instance_type: Some(InstanceType::String.into()),
50                string: Some(
51                    StringValidation {
52                        pattern: Some(format!("^{}:", C::CURVE_TYPE)),
53                        ..Default::default()
54                    }
55                    .into(),
56                ),
57                extensions: [("contentEncoding", "base58".into())]
58                    .into_iter()
59                    .map(|(k, v)| (k.to_string(), v))
60                    .collect(),
61                ..Default::default()
62            }
63            .into()
64        }
65
66        fn is_referenceable() -> bool {
67            false
68        }
69    }
70};