git_bug/replica/entity/
nonce.rs1use base64::{Engine, prelude::BASE64_STANDARD};
15use serde::{Deserialize, Serialize};
16
17#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)]
21pub(crate) struct Nonce {
22 first: [Option<u8>; 32],
25 second: [Option<u8>; 32],
26}
27
28impl TryFrom<String> for Nonce {
29 type Error = base64::DecodeSliceError;
30
31 fn try_from(value: String) -> Result<Self, Self::Error> {
32 <Self as TryFrom<&str>>::try_from(&value)
33 }
34}
35impl TryFrom<&str> for Nonce {
36 type Error = base64::DecodeSliceError;
37
38 fn try_from(value: &str) -> Result<Self, Self::Error> {
39 let mut buffer = [0; 64];
42
43 let written = BASE64_STANDARD.decode_slice(value, &mut buffer)?;
44
45 let mut output = [None; 64];
46 for (slot, byte) in output.iter_mut().zip(buffer[..written].iter()) {
47 *slot = Some(*byte);
48 }
49
50 let mut first = [None; 32];
51 first.copy_from_slice(&output[..32]);
52
53 let mut second = [None; 32];
54 second.copy_from_slice(&output[32..]);
55
56 Ok(Self { first, second })
57 }
58}
59
60impl From<Nonce> for String {
61 fn from(value: Nonce) -> Self {
62 let mut buffer = String::new();
63
64 let mut index = 0;
65 let mut payload = [0; 64];
66 for (slot, maybe_byte) in payload
67 .iter_mut()
68 .zip(value.first.iter().chain(value.second.iter()))
69 {
70 if let Some(byte) = maybe_byte {
71 *slot = *byte;
72 index += 1;
73 }
74 }
75
76 let trimmed_payload = &payload[..index];
77
78 BASE64_STANDARD.encode_string(trimmed_payload, &mut buffer);
79 buffer
80 }
81}