Skip to main content

rings_core/message/
encoder.rs

1use std::ops::Deref;
2
3use base58_monero as b58m;
4use bytes::Bytes;
5use serde::Deserialize;
6use serde::Serialize;
7
8use crate::error::Error;
9use crate::error::Result;
10
11pub trait Encoder {
12    fn encode(&self) -> Result<Encoded>;
13}
14
15pub trait Decoder: Sized {
16    fn from_encoded(encoded: &Encoded) -> Result<Self>;
17}
18
19#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
20pub struct Encoded(String);
21
22impl Encoded {
23    pub fn value(&self) -> &String {
24        &self.0
25    }
26}
27
28impl Deref for Encoded {
29    type Target = String;
30    fn deref(&self) -> &Self::Target {
31        self.value()
32    }
33}
34
35impl Encoder for String {
36    fn encode(&self) -> Result<Encoded> {
37        Ok(Encoded(
38            b58m::encode_check(self.as_bytes()).map_err(|_| Error::Encode)?,
39        ))
40    }
41}
42
43impl Decoder for String {
44    fn from_encoded(encoded: &Encoded) -> Result<String> {
45        let d = Vec::from_encoded(encoded)?;
46        String::from_utf8(d).map_err(|_| Error::Decode)
47    }
48}
49
50impl Encoder for &str {
51    fn encode(&self) -> Result<Encoded> {
52        self.as_bytes().encode()
53    }
54}
55
56impl Encoder for &[u8] {
57    fn encode(&self) -> Result<Encoded> {
58        Ok(Encoded(
59            b58m::encode_check(self).map_err(|_| Error::Encode)?,
60        ))
61    }
62}
63
64impl Encoder for Vec<u8> {
65    fn encode(&self) -> Result<Encoded> {
66        Ok(Encoded(
67            b58m::encode_check(self).map_err(|_| Error::Encode)?,
68        ))
69    }
70}
71
72impl Encoder for Bytes {
73    fn encode(&self) -> Result<Encoded> {
74        self.as_ref().encode()
75    }
76}
77
78impl Decoder for Vec<u8> {
79    fn from_encoded(encoded: &Encoded) -> Result<Self> {
80        b58m::decode_check(encoded.deref()).map_err(|_| Error::Decode)
81    }
82}
83
84impl Decoder for Bytes {
85    fn from_encoded(encoded: &Encoded) -> Result<Self> {
86        let d = Vec::from_encoded(encoded)?;
87        Ok(Bytes::from(d))
88    }
89}
90
91#[allow(clippy::to_string_trait_impl)]
92impl ToString for Encoded {
93    fn to_string(&self) -> String {
94        self.deref().to_owned()
95    }
96}
97
98impl From<String> for Encoded {
99    fn from(v: String) -> Self {
100        Self(v)
101    }
102}
103
104impl From<&str> for Encoded {
105    fn from(v: &str) -> Self {
106        Self(v.to_owned())
107    }
108}
109
110impl From<Encoded> for Vec<u8> {
111    fn from(a: Encoded) -> Self {
112        a.to_string().as_bytes().to_vec()
113    }
114}
115
116impl TryFrom<Vec<u8>> for Encoded {
117    type Error = Error;
118    fn try_from(a: Vec<u8>) -> Result<Self> {
119        let s: String = String::from_utf8(a)?;
120        Ok(s.into())
121    }
122}
123
124impl Encoded {
125    pub fn from_encoded_str(str: &str) -> Self {
126        Self(str.to_owned())
127    }
128
129    pub fn decode<T>(&self) -> Result<T>
130    where T: Decoder {
131        T::from_encoded(self)
132    }
133}
134
135#[cfg(test)]
136mod test {
137    use super::*;
138
139    #[test]
140    fn test_encode_decode() {
141        let test1 = vec![1, 2, 3, 4];
142
143        let encoded1 = test1.encode().unwrap();
144        let result1: Vec<u8> = encoded1.decode().unwrap();
145        assert_eq!(test1, result1);
146
147        let test1 = test1.as_slice();
148        let encoded1 = test1.encode().unwrap();
149        let result1: Vec<u8> = encoded1.decode().unwrap();
150        assert_eq!(test1, result1);
151
152        let test2 = "abc";
153        let encoded2 = test2.encode().unwrap();
154        let result2: String = encoded2.decode().unwrap();
155        assert_eq!(test2, result2);
156
157        let test3 = String::from("abc");
158        let encoded3 = test3.encode().unwrap();
159        let result3: String = encoded3.decode().unwrap();
160        assert_eq!(test3, result3);
161    }
162
163    #[test]
164    fn test_from_encoded() {
165        let source = [1u8; 32].to_vec();
166        let encoded = source.encode().unwrap();
167        let v = encoded.to_string();
168        let v2 = Encoded::from_encoded_str(&v);
169        assert_eq!(encoded, v2);
170    }
171}