mithril_common/crypto_helper/codec/
json_hex.rs

1use crate::entities::{HexEncodedKey, HexEncodedKeySlice};
2
3use hex::{FromHex, ToHex};
4use serde::Serialize;
5use serde::de::DeserializeOwned;
6use thiserror::Error;
7
8/// Error raised when the encoding or decoding fails
9#[derive(Error, Debug)]
10#[error("Codec error: {msg}")]
11pub struct CodecError {
12    msg: String,
13    #[source]
14    source: anyhow::Error,
15}
16
17impl CodecError {
18    /// [CodecError] factory.
19    pub fn new(msg: &str, source: anyhow::Error) -> Self {
20        Self {
21            msg: msg.to_string(),
22            source,
23        }
24    }
25}
26
27/// Encode key to hex helper
28pub fn key_encode_hex<T>(from: T) -> Result<HexEncodedKey, CodecError>
29where
30    T: Serialize,
31{
32    Ok(serde_json::to_string(&from)
33        .map_err(|e| CodecError::new("Key encode hex: can not convert to hex", e.into()))?
34        .encode_hex::<String>())
35}
36
37/// Decode key from hex helper
38pub fn key_decode_hex<T>(from: HexEncodedKeySlice) -> Result<T, CodecError>
39where
40    T: DeserializeOwned,
41{
42    let from_vec = Vec::from_hex(from.trim()).map_err(|e| {
43        CodecError::new(
44            "Key decode hex: can not turn hexadecimal value into bytes",
45            e.into(),
46        )
47    })?;
48    serde_json::from_slice(from_vec.as_slice()).map_err(|e| {
49        CodecError::new(
50            &format!(
51                "Key decode hex: can not deserialize to type '{}' from binary JSON",
52                std::any::type_name::<T>()
53            ),
54            e.into(),
55        )
56    })
57}
58
59#[cfg(test)]
60mod tests {
61    use serde::{Deserialize, Serialize};
62
63    use super::{key_decode_hex, key_encode_hex};
64
65    #[derive(Debug, PartialEq, Serialize, Deserialize)]
66    struct TestSerialize {
67        inner_string: String,
68    }
69
70    #[test]
71    fn test_key_encode_decode_hex() {
72        let test_to_serialize = TestSerialize {
73            inner_string: "my inner string".to_string(),
74        };
75        let test_to_serialize_hex =
76            key_encode_hex(&test_to_serialize).expect("unexpected hex encoding error");
77        let test_to_serialize_restored =
78            key_decode_hex(&test_to_serialize_hex).expect("unexpected hex decoding error");
79        assert_eq!(test_to_serialize, test_to_serialize_restored);
80    }
81
82    #[test]
83    fn test_key_decode_hex_with_leading_and_trailing_whitespace() {
84        let test_to_serialize = TestSerialize {
85            inner_string: "my inner string".to_string(),
86        };
87        let test_to_serialize_hex =
88            key_encode_hex(&test_to_serialize).expect("unexpected hex encoding error");
89        let test_to_serialize_restored = key_decode_hex(&format!(" \r{test_to_serialize_hex} \n"))
90            .expect("unexpected hex decoding error");
91        assert_eq!(test_to_serialize, test_to_serialize_restored);
92    }
93}