defuse_core/nonce/
salted.rs1use 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}