serde_xrpl/
types.rs

1use crate::error::{Error, Result};
2use crate::utils::{decode_base58, encode_issued_currency_amount, encode_variable_length};
3use std::collections::HashMap;
4
5pub enum Field {}
6
7pub trait ToTypeCode {
8    fn to_type_code() -> u16;
9}
10
11macro_rules! type_code {
12    ($name: ident, $type_code: expr) => {
13        impl ToTypeCode for $name {
14            fn to_type_code() -> u16 {
15                $type_code
16            }
17        }
18    };
19}
20
21// type_code(Validation, 10003);
22// type_code(Done, -1);
23type_code!(Hash128, 4);
24type_code!(Blob, 7);
25type_code!(AccountID, 8);
26type_code!(Amount, 6);
27type_code!(Hash256, 5);
28type_code!(u8, 16);
29type_code!(Vector256, 19);
30type_code!(STObject, 14);
31// type_code!(Unknown, -2);
32// type_code!(Transaction, 10001);
33type_code!(Hash160, 17);
34// type_code!(PathSet, 18);
35// type_code!(LedgerEntry, 10002);
36type_code!(u16, 1);
37// type_code!(NotPresent, 0);
38type_code!(u64, 3);
39type_code!(u32, 2);
40type_code!(STArray, 15);
41
42#[derive(Debug, Clone)]
43pub enum Value {
44    Hash128(String),
45    Blob(Blob),
46    AccountID(String),
47    Amount(Amount),
48    Hash256(Hash256),
49    UInt8(u8),
50    Vector256(Vector256),
51    STObject(STObject),
52    Unknown,
53    Transaction(u16),
54    Hash160(Hash160),
55    PathSet,
56    LedgerEntry,
57    UInt16(u16),
58    NotPresent,
59    UInt64(u64),
60    UInt32(u32),
61    STArray(Vec<Value>),
62}
63
64impl Value {
65    pub fn to_bytes(&self) -> Result<Vec<u8>> {
66        match self {
67            Self::AccountID(account_id) => {
68                let address = decode_base58(account_id, &[0x0])?;
69                let length = encode_variable_length(address.len());
70                Ok([length, address].concat())
71            }
72            Self::Amount(amount) => amount.to_bytes(),
73            Self::UInt8(u) => Ok(u.to_be_bytes().to_vec()),
74            Self::UInt16(u) => Ok(u.to_be_bytes().to_vec()),
75            Self::UInt32(u) => Ok(u.to_be_bytes().to_vec()),
76            Self::UInt64(u) => Ok(u.to_be_bytes().to_vec()),
77            Self::Blob(blob) => {
78                let data = hex::decode(&blob.0).unwrap();
79                let length = encode_variable_length(data.len());
80                Ok([length, data].concat())
81            }
82            Self::Transaction(tx) => Ok(tx.to_be_bytes().to_vec()),
83            Self::Hash256(hash) => Ok(hash.to_bytes().to_vec()),
84            Self::Vector256(v) => {
85                let data: Vec<u8> =
86                    v.0.iter()
87                        .map(|h| hex::decode(&h.0).unwrap().to_vec())
88                        .flatten()
89                        .collect();
90                let length = encode_variable_length(data.len());
91                Ok([length, data].concat())
92            }
93            _ => {
94                unimplemented!()
95            }
96        }
97    }
98}
99
100#[derive(Debug, Clone)]
101pub struct Hash160(pub String);
102
103#[derive(Debug, Clone)]
104pub struct Hash128(pub String);
105
106#[derive(Debug, Clone)]
107pub struct Hash256(pub String);
108
109impl Hash256 {
110    pub fn to_bytes(&self) -> Vec<u8> {
111        hex::decode(&self.0).unwrap().to_vec()
112    }
113}
114
115#[derive(Debug, Clone)]
116pub struct AccountID([u8; 20]);
117
118impl AccountID {
119    pub fn from_str(s: &str) -> Result<AccountID> {
120        decode_base58(s, &[0x00]).map(|bytes| {
121            if bytes.len() == 20 {
122                return Ok(Self(bytes.try_into().map_err(|_| Error::InvalidAddress)?));
123            }
124            Err(Error::InvalidAddress)
125        })?
126    }
127}
128
129#[derive(Debug, Clone)]
130pub enum Amount {
131    XRP(u64),
132    IssuedCurrency {
133        value: String,
134        currency: String,
135        issuer: String,
136    },
137}
138
139impl Amount {
140    pub fn to_bytes(&self) -> Result<Vec<u8>> {
141        match self {
142            Self::XRP(amount) => Ok((amount | 0x4000000000000000u64).to_be_bytes().to_vec()),
143            Self::IssuedCurrency {
144                value,
145                currency,
146                issuer,
147            } => encode_issued_currency_amount(&value, &currency, &issuer),
148        }
149    }
150}
151
152#[derive(Debug, Clone)]
153pub struct STObject(HashMap<String, Value>);
154
155#[derive(Debug, Clone)]
156pub struct Blob(pub String);
157
158#[derive(Debug, Clone)]
159pub struct STArray(Vec<Value>);
160
161#[derive(Debug, Clone)]
162pub struct Vector256(pub Vec<Hash256>);