pallas_crypto/hash/
serde.rs1use std::fmt;
2use std::str::FromStr;
3
4use serde::de::{Error, Unexpected, Visitor};
5use serde::{Deserialize, Deserializer, Serialize};
6
7use super::Hash;
8
9impl<const BYTES: usize> Serialize for Hash<BYTES> {
10 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
11 where
12 S: serde::Serializer,
13 {
14 serializer.serialize_str(&self.to_string())
15 }
16}
17
18struct HashVisitor<const BYTES: usize> {}
19
20impl<const BYTES: usize> Visitor<'_> for HashVisitor<BYTES> {
21 type Value = Hash<BYTES>;
22
23 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
24 write!(formatter, "a hex string representing {BYTES} bytes")
25 }
26
27 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
28 where
29 E: Error,
30 {
31 match Hash::<BYTES>::from_str(s) {
32 Ok(x) => Ok(x),
33 Err(_) => Err(Error::invalid_value(Unexpected::Str(s), &self)),
34 }
35 }
36}
37
38impl<'de, const BYTES: usize> Deserialize<'de> for Hash<BYTES> {
39 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
40 where
41 D: Deserializer<'de>,
42 {
43 deserializer.deserialize_str(HashVisitor::<BYTES> {})
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use serde_test::{assert_de_tokens_error, assert_tokens, Token};
50
51 use super::*;
52
53 #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
54 struct Dummy {
55 hash1: Hash<28>,
56 hash2: Hash<32>,
57 }
58
59 #[test]
60 fn output_tokens() {
61 let dummy = Dummy {
62 hash1: "276fd18711931e2c0e21430192dbeac0e458093cd9d1fcd7210f64b3"
63 .parse()
64 .unwrap(),
65 hash2: "0d8d00cdd4657ac84d82f0a56067634a7adfdf43da41cb534bcaa45060973d21"
66 .parse()
67 .unwrap(),
68 };
69
70 assert_tokens(
71 &dummy,
72 &[
73 Token::Struct {
74 name: "Dummy",
75 len: 2,
76 },
77 Token::Str("hash1"),
78 Token::Str("276fd18711931e2c0e21430192dbeac0e458093cd9d1fcd7210f64b3"),
79 Token::Str("hash2"),
80 Token::Str("0d8d00cdd4657ac84d82f0a56067634a7adfdf43da41cb534bcaa45060973d21"),
81 Token::StructEnd,
82 ],
83 );
84 }
85
86 #[test]
87 fn invalid_str() {
88 assert_de_tokens_error::<Dummy>(
89 &[
90 Token::Map { len: Some(2) },
91 Token::Str("hash1"),
92 Token::Str("27"),
93 ],
94 "invalid value: string \"27\", expected a hex string representing 28 bytes",
95 );
96 }
97}