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")))]
30mod abi {
31    use super::*;
32
33    use near_sdk::schemars::{
34        JsonSchema,
35        r#gen::SchemaGenerator,
36        schema::{InstanceType, Schema, SchemaObject, StringValidation},
37    };
38    use serde_with::schemars_0_8::JsonSchemaAs;
39
40    impl<C: TypedCurve, const N: usize> JsonSchemaAs<[u8; N]> for AsCurve<C> {
41        fn schema_name() -> String {
42            String::schema_name()
43        }
44
45        fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
46            SchemaObject {
47                instance_type: Some(InstanceType::String.into()),
48                string: Some(
49                    StringValidation {
50                        pattern: Some(format!("^{}:", C::CURVE_TYPE)),
51                        ..Default::default()
52                    }
53                    .into(),
54                ),
55                extensions: [("contentEncoding", "base58".into())]
56                    .into_iter()
57                    .map(|(k, v)| (k.to_string(), v))
58                    .collect(),
59                ..Default::default()
60            }
61            .into()
62        }
63
64        fn is_referenceable() -> bool {
65            false
66        }
67    }
68}