1use crate::{Error, Result};
2use rand::Rng;
3use serde::{Deserialize, Serialize};
4use std::{fmt, str::FromStr};
5
6#[derive(Debug, Serialize, Deserialize, Clone, Copy, Hash, Eq, PartialEq)]
11#[serde(try_from = "String", into = "String")]
12pub struct AccountId([u8; 20]);
13
14impl AccountId {
15 pub fn random() -> Self {
17 let mut rng = crate::csprng();
18 Self(rng.gen())
19 }
20}
21
22impl fmt::Display for AccountId {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 write!(f, "0x{}", hex::encode(self.0))
25 }
26}
27
28impl Default for AccountId {
29 fn default() -> Self {
30 Self([0u8; 20])
31 }
32}
33
34impl AsRef<[u8]> for AccountId {
35 fn as_ref(&self) -> &[u8] {
36 &self.0
37 }
38}
39
40impl From<[u8; 20]> for AccountId {
41 fn from(value: [u8; 20]) -> Self {
42 Self(value)
43 }
44}
45
46impl FromStr for AccountId {
47 type Err = Error;
48
49 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
50 if !s.starts_with("0x") {
51 return Err(Error::BadAccountIdPrefix);
52 }
53 let bytes = hex::decode(&s[2..])?;
54 let buffer: [u8; 20] = bytes.as_slice().try_into()?;
55 Ok(AccountId(buffer))
56 }
57}
58
59impl From<AccountId> for String {
60 fn from(value: AccountId) -> String {
61 value.to_string()
62 }
63}
64
65impl From<AccountId> for [u8; 20] {
66 fn from(value: AccountId) -> [u8; 20] {
67 value.0
68 }
69}
70
71impl TryFrom<String> for AccountId {
72 type Error = Error;
73 fn try_from(value: String) -> Result<Self> {
74 <AccountId as FromStr>::from_str(&value)
75 }
76}