tari_utilities/
encoding.rs1use alloc::string::{String, ToString};
26
27use snafu::prelude::*;
28
29use crate::ByteArray;
30
31#[deprecated(since = "0.8.0", note = "please use `MBase58` instead")]
33pub trait Base58 {
34 fn from_base58(hex: &str) -> Result<Self, Base58Error>
36 where Self: Sized;
37
38 fn to_base58(&self) -> String;
40}
41
42#[derive(Debug, Snafu)]
44#[allow(missing_docs)]
45pub enum Base58Error {
46 #[snafu(display("Byte array error: `{reason}'"))]
47 ByteArrayError { reason: String },
48 #[snafu(display("Decode error: `{reason}'"))]
49 DecodeError { reason: String },
50}
51
52#[allow(deprecated)]
53impl<T: ByteArray> Base58 for T {
54 fn from_base58(data: &str) -> Result<Self, Base58Error>
55 where Self: Sized {
56 let bytes = base58_monero::decode(data).map_err(|e| Base58Error::DecodeError { reason: e.to_string() })?;
57 Self::from_canonical_bytes(&bytes).map_err(|e| Base58Error::ByteArrayError { reason: e.to_string() })
58 }
59
60 fn to_base58(&self) -> String {
61 base58_monero::encode(self.as_bytes()).expect("base58_monero::encode is infallible")
62 }
63}
64
65pub trait MBase58 {
67 fn from_monero_base58(hex: &str) -> Result<Self, Base58Error>
69 where Self: Sized;
70
71 fn to_monero_base58(&self) -> String;
73}
74
75impl<T: ByteArray> crate::encoding::MBase58 for T {
76 fn from_monero_base58(data: &str) -> Result<Self, Base58Error>
77 where Self: Sized {
78 let bytes = base58_monero::decode(data).map_err(|e| Base58Error::DecodeError { reason: e.to_string() })?;
79 Self::from_canonical_bytes(&bytes)
80 .map_err(|e| crate::encoding::Base58Error::ByteArrayError { reason: e.to_string() })
81 }
82
83 fn to_monero_base58(&self) -> String {
84 base58_monero::encode(self.as_bytes()).expect("base58_monero::encode is infallible")
85 }
86}
87
88#[cfg(test)]
89mod test {
90 use alloc::vec::Vec;
91
92 use rand_core::{OsRng, RngCore};
93
94 use super::*;
95
96 #[test]
97 fn decoding() {
98 assert_eq!(Vec::from_monero_base58("111111").unwrap(), vec![0; 4]);
99 assert_eq!(Vec::from_monero_base58("11115Q").unwrap(), vec![0, 0, 0, 255]);
100 assert!(Vec::from_monero_base58("11111O").is_err());
101 assert!(Vec::from_monero_base58("🖖🥴").is_err());
102 }
103
104 #[test]
105 fn encoding() {
106 assert_eq!(vec![0; 4].to_monero_base58(), "111111");
107 assert_eq!(vec![0, 2, 250, 39].to_monero_base58(), "111zzz");
108 }
109
110 #[test]
111 fn inverse_operations() {
112 let mut bytes = vec![0; 10];
113 OsRng.fill_bytes(&mut bytes);
114 assert_eq!(Vec::from_monero_base58(&bytes.to_monero_base58()).unwrap(), bytes);
115 }
116}