1use crate::{Error, Result};
2use rand::Rng;
3use serde::{Deserialize, Serialize};
4use std::{fmt, str::FromStr};
5
6#[derive(Debug, Default, 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 AsRef<[u8]> for AccountId {
29 fn as_ref(&self) -> &[u8] {
30 &self.0
31 }
32}
33
34impl From<[u8; 20]> for AccountId {
35 fn from(value: [u8; 20]) -> Self {
36 Self(value)
37 }
38}
39
40impl FromStr for AccountId {
41 type Err = Error;
42
43 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
44 if !s.starts_with("0x") {
45 return Err(Error::BadAccountIdPrefix);
46 }
47 let bytes = hex::decode(&s[2..])?;
48 let buffer: [u8; 20] = bytes.as_slice().try_into()?;
49 Ok(AccountId(buffer))
50 }
51}
52
53impl From<AccountId> for String {
54 fn from(value: AccountId) -> String {
55 value.to_string()
56 }
57}
58
59impl From<AccountId> for [u8; 20] {
60 fn from(value: AccountId) -> [u8; 20] {
61 value.0
62 }
63}
64
65impl TryFrom<String> for AccountId {
66 type Error = Error;
67 fn try_from(value: String) -> Result<Self> {
68 <AccountId as FromStr>::from_str(&value)
69 }
70}