outmove_common/types/
account_address.rs1use anyhow::{ensure, Error, Result};
5use rand::{rngs::OsRng, Rng};
6use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
7use std::{convert::TryFrom, fmt, str::FromStr};
8
9#[derive(Ord, PartialOrd, Eq, PartialEq, Hash, Clone, Copy)]
11pub struct AccountAddress([u8; AccountAddress::LENGTH]);
12
13impl AccountAddress {
14 pub const fn new(address: [u8; Self::LENGTH]) -> Self {
15 Self(address)
16 }
17
18 pub const LENGTH: usize = 16;
20
21 pub const ZERO: Self = Self([0u8; Self::LENGTH]);
23
24 pub fn random() -> Self {
25 let mut rng = OsRng;
26 let buf: [u8; Self::LENGTH] = rng.gen();
27 Self(buf)
28 }
29
30 pub fn short_str_lossless(&self) -> String {
31 let hex_str = hex::encode(&self.0).trim_start_matches('0').to_string();
32 if hex_str.is_empty() {
33 "0".to_string()
34 } else {
35 hex_str
36 }
37 }
38
39 pub fn to_vec(&self) -> Vec<u8> {
40 self.0.to_vec()
41 }
42
43 pub fn to_u8(self) -> [u8; Self::LENGTH] {
44 self.0
45 }
46
47 pub fn from_hex_literal(literal: &str) -> Result<Self> {
48 ensure!(literal.starts_with("0x"), "literal must start with 0x.");
49
50 let hex_len = literal.len() - 2;
51 let mut result = if hex_len % 2 != 0 {
52 let mut hex_str = String::with_capacity(hex_len + 1);
53 hex_str.push('0');
54 hex_str.push_str(&literal[2..]);
55 hex::decode(&hex_str)?
56 } else {
57 hex::decode(&literal[2..])?
58 };
59
60 let len = result.len();
61 let padded_result = if len < Self::LENGTH {
62 let mut padded = Vec::with_capacity(Self::LENGTH);
63 padded.resize(Self::LENGTH - len, 0u8);
64 padded.append(&mut result);
65 padded
66 } else {
67 result
68 };
69
70 AccountAddress::try_from(padded_result)
71 }
72}
73
74impl AsRef<[u8]> for AccountAddress {
75 fn as_ref(&self) -> &[u8] {
76 &self.0
77 }
78}
79
80impl fmt::Display for AccountAddress {
81 fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
82 write!(f, "{:#X}", self)
84 }
85}
86
87impl fmt::Debug for AccountAddress {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 write!(f, "{:#X}", self)
91 }
92}
93
94impl fmt::LowerHex for AccountAddress {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 write!(f, "{}", hex::encode(&self.0))
97 }
98}
99
100impl fmt::UpperHex for AccountAddress {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 write!(f, "{}", hex::encode_upper(&self.0))
103 }
104}
105
106impl TryFrom<&[u8]> for AccountAddress {
107 type Error = Error;
108
109 fn try_from(bytes: &[u8]) -> Result<AccountAddress> {
111 ensure!(
112 bytes.len() == Self::LENGTH,
113 "The Address {:?} is of invalid length",
114 bytes
115 );
116 let mut addr = [0u8; Self::LENGTH];
117 addr.copy_from_slice(bytes);
118 Ok(AccountAddress(addr))
119 }
120}
121
122impl TryFrom<&[u8; AccountAddress::LENGTH]> for AccountAddress {
123 type Error = Error;
124
125 fn try_from(bytes: &[u8; Self::LENGTH]) -> Result<AccountAddress> {
127 AccountAddress::try_from(&bytes[..])
128 }
129}
130
131impl TryFrom<Vec<u8>> for AccountAddress {
132 type Error = Error;
133
134 fn try_from(bytes: Vec<u8>) -> Result<AccountAddress> {
136 AccountAddress::try_from(&bytes[..])
137 }
138}
139
140impl From<AccountAddress> for Vec<u8> {
141 fn from(addr: AccountAddress) -> Vec<u8> {
142 addr.0.to_vec()
143 }
144}
145
146impl From<&AccountAddress> for Vec<u8> {
147 fn from(addr: &AccountAddress) -> Vec<u8> {
148 addr.0.to_vec()
149 }
150}
151
152impl From<AccountAddress> for [u8; AccountAddress::LENGTH] {
153 fn from(addr: AccountAddress) -> Self {
154 addr.0
155 }
156}
157
158impl From<&AccountAddress> for [u8; AccountAddress::LENGTH] {
159 fn from(addr: &AccountAddress) -> Self {
160 addr.0
161 }
162}
163
164impl From<&AccountAddress> for String {
165 fn from(addr: &AccountAddress) -> String {
166 ::hex::encode(addr.as_ref())
167 }
168}
169
170impl TryFrom<String> for AccountAddress {
171 type Error = Error;
172
173 fn try_from(s: String) -> Result<AccountAddress> {
174 let bytes_out = ::hex::decode(s)?;
175 AccountAddress::try_from(bytes_out.as_slice())
176 }
177}
178
179impl FromStr for AccountAddress {
180 type Err = Error;
181
182 fn from_str(s: &str) -> Result<Self> {
183 let bytes_out = ::hex::decode(s)?;
184 AccountAddress::try_from(bytes_out.as_slice())
185 }
186}
187
188#[derive(Deserialize)]
189#[serde(rename = "AccountAddress")]
190struct DeserializeValue([u8; AccountAddress::LENGTH]);
191
192impl<'de> Deserialize<'de> for AccountAddress {
193 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
194 where
195 D: Deserializer<'de>,
196 {
197 if deserializer.is_human_readable() {
198 let s = <String>::deserialize(deserializer)?;
199 AccountAddress::try_from(s).map_err(D::Error::custom)
200 } else {
201 let value = DeserializeValue::deserialize(deserializer)?;
202 Ok(AccountAddress::new(value.0))
203 }
204 }
205}
206
207impl Serialize for AccountAddress {
208 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
209 where
210 S: Serializer,
211 {
212 if serializer.is_human_readable() {
213 self.to_string().serialize(serializer)
214 } else {
215 serializer.serialize_newtype_struct("AccountAddress", &self.0)
217 }
218 }
219}