rings_core/message/
encoder.rs1use 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}