defuse_crypto/serde/
curve.rs

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