crypto/encoding/ternary/
serde.rs

1// Copyright 2020-2021 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use core::{convert::TryFrom, fmt, marker::PhantomData};
5
6use serde::{
7    de::{Error, SeqAccess, Unexpected, Visitor},
8    ser::SerializeSeq,
9    Deserialize, Deserializer, Serialize, Serializer,
10};
11
12use crate::encoding::ternary::{Btrit, RawEncoding, RawEncodingBuf, TritBuf, Trits, Utrit};
13
14// Serialisation
15
16impl Serialize for Btrit {
17    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
18        serializer.serialize_i8((*self).into())
19    }
20}
21
22impl Serialize for Utrit {
23    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
24        serializer.serialize_i8((*self).into())
25    }
26}
27
28impl<'a, T: RawEncoding> Serialize for &'a Trits<T>
29where
30    T::Trit: Serialize,
31    T: serde::Serialize,
32{
33    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
34        let mut seq = serializer.serialize_seq(Some(self.len()))?;
35        for trit in self.iter() {
36            seq.serialize_element(&trit)?;
37        }
38        seq.end()
39    }
40}
41
42impl<T: RawEncodingBuf> Serialize for TritBuf<T>
43where
44    <T::Slice as RawEncoding>::Trit: Serialize,
45{
46    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
47        let mut seq = serializer.serialize_seq(Some(self.len()))?;
48        for trit in self.iter() {
49            seq.serialize_element(&trit)?;
50        }
51        seq.end()
52    }
53}
54
55// Deserialisation
56
57struct BtritVisitor;
58
59impl<'de> Visitor<'de> for BtritVisitor {
60    type Value = Btrit;
61
62    fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
63        f.write_str("a value between -1 and 1 inclusive")
64    }
65
66    fn visit_u64<E: Error>(self, trit: u64) -> Result<Self::Value, E> {
67        i8::try_from(trit)
68            .map_err(|_| ())
69            .and_then(|trit| Btrit::try_from(trit).map_err(|_| ()))
70            .map_err(|_| E::invalid_value(Unexpected::Unsigned(trit), &self))
71    }
72
73    fn visit_i64<E: Error>(self, trit: i64) -> Result<Self::Value, E> {
74        i8::try_from(trit)
75            .map_err(|_| ())
76            .and_then(|trit| Btrit::try_from(trit).map_err(|_| ()))
77            .map_err(|_| E::invalid_value(Unexpected::Signed(trit), &self))
78    }
79
80    fn visit_u8<E: Error>(self, trit: u8) -> Result<Self::Value, E> {
81        i8::try_from(trit)
82            .map_err(|_| ())
83            .and_then(|trit| Btrit::try_from(trit).map_err(|_| ()))
84            .map_err(|_| E::invalid_value(Unexpected::Unsigned(trit as u64), &self))
85    }
86
87    fn visit_i8<E: Error>(self, trit: i8) -> Result<Self::Value, E> {
88        Btrit::try_from(trit).map_err(|_| E::invalid_value(Unexpected::Signed(trit as i64), &self))
89    }
90}
91
92impl<'de> Deserialize<'de> for Btrit {
93    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
94        deserializer.deserialize_i8(BtritVisitor)
95    }
96}
97
98struct UtritVisitor;
99
100impl<'de> Visitor<'de> for UtritVisitor {
101    type Value = Utrit;
102
103    fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
104        f.write_str("a value between 0 and 2 inclusive")
105    }
106
107    fn visit_u64<E: Error>(self, trit: u64) -> Result<Self::Value, E> {
108        u8::try_from(trit)
109            .map_err(|_| ())
110            .and_then(|trit| Utrit::try_from(trit).map_err(|_| ()))
111            .map_err(|_| E::invalid_value(Unexpected::Unsigned(trit), &self))
112    }
113
114    fn visit_i64<E: Error>(self, trit: i64) -> Result<Self::Value, E> {
115        i8::try_from(trit)
116            .map_err(|_| ())
117            .and_then(|trit| Utrit::try_from(trit).map_err(|_| ()))
118            .map_err(|_| E::invalid_value(Unexpected::Signed(trit), &self))
119    }
120
121    fn visit_u8<E: Error>(self, trit: u8) -> Result<Self::Value, E> {
122        Ok(trit)
123            .and_then(|trit| Utrit::try_from(trit).map_err(|_| ()))
124            .map_err(|_| E::invalid_value(Unexpected::Unsigned(trit as u64), &self))
125    }
126
127    fn visit_i8<E: Error>(self, trit: i8) -> Result<Self::Value, E> {
128        Utrit::try_from(trit).map_err(|_| E::invalid_value(Unexpected::Signed(trit as i64), &self))
129    }
130}
131
132impl<'de> Deserialize<'de> for Utrit {
133    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
134        deserializer.deserialize_i8(UtritVisitor)
135    }
136}
137
138struct TritBufVisitor<T>(PhantomData<T>);
139
140impl<'de, T: RawEncodingBuf> Visitor<'de> for TritBufVisitor<T>
141where
142    <T::Slice as RawEncoding>::Trit: Deserialize<'de>,
143{
144    type Value = TritBuf<T>;
145
146    fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
147        f.write_str("a sequence of trits")
148    }
149
150    fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
151        let mut buf = TritBuf::with_capacity(seq.size_hint().unwrap_or(0));
152
153        while let Some(trit) = seq.next_element()? {
154            buf.push(trit);
155        }
156
157        Ok(buf)
158    }
159}
160
161impl<'de, T: RawEncodingBuf> Deserialize<'de> for TritBuf<T>
162where
163    <T::Slice as RawEncoding>::Trit: Deserialize<'de>,
164{
165    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
166        deserializer.deserialize_seq(TritBufVisitor::<T>(PhantomData))
167    }
168}