Skip to main content

defuse_core/nonce/
salted.rs

1use borsh::{BorshDeserialize, BorshSerialize};
2use hex::FromHex;
3use serde_with::{DeserializeFromStr, SerializeDisplay};
4use std::{
5    fmt::{self, Debug},
6    str::FromStr,
7};
8
9use crate::Result;
10
11#[cfg_attr(any(feature = "arbitrary", test), derive(arbitrary::Arbitrary))]
12#[cfg_attr(feature = "borsh-schema", derive(::borsh::BorshSchema))]
13#[derive(
14    Clone,
15    Copy,
16    PartialEq,
17    Eq,
18    PartialOrd,
19    Ord,
20    SerializeDisplay,
21    DeserializeFromStr,
22    BorshSerialize,
23    BorshDeserialize,
24)]
25#[repr(transparent)]
26pub struct Salt(pub [u8; 4]);
27
28impl fmt::Debug for Salt {
29    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
30        write!(f, "{}", hex::encode(self.0))
31    }
32}
33
34impl fmt::Display for Salt {
35    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36        Debug::fmt(self, f)
37    }
38}
39
40impl FromStr for Salt {
41    type Err = hex::FromHexError;
42
43    fn from_str(s: &str) -> Result<Self, Self::Err> {
44        FromHex::from_hex(s).map(Self)
45    }
46}
47
48#[cfg(feature = "schemars-v0_8")]
49const _: () = {
50    use schemars::{
51        JsonSchema,
52        r#gen::SchemaGenerator,
53        schema::{InstanceType, Schema, SchemaObject},
54    };
55
56    impl JsonSchema for Salt {
57        fn schema_name() -> String {
58            String::schema_name()
59        }
60
61        fn is_referenceable() -> bool {
62            false
63        }
64
65        fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
66            SchemaObject {
67                instance_type: Some(InstanceType::String.into()),
68                extensions: std::iter::once(("contentEncoding", "hex".into()))
69                    .map(|(k, v)| (k.to_string(), v))
70                    .collect(),
71                ..Default::default()
72            }
73            .into()
74        }
75    }
76};
77
78#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
79pub struct SaltedNonce<T>
80where
81    T: BorshSerialize + BorshDeserialize,
82{
83    pub salt: Salt,
84    pub nonce: T,
85}
86
87impl<T> SaltedNonce<T>
88where
89    T: BorshSerialize + BorshDeserialize,
90{
91    pub const fn new(salt: Salt, nonce: T) -> Self {
92        Self { salt, nonce }
93    }
94}