hypersync_format/types/
transaction_status.rs

1use crate::{Error, Result};
2use serde::de::{self, Visitor};
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use std::fmt;
5use std::result::Result as StdResult;
6use std::str::FromStr;
7
8use super::Hex;
9
10#[derive(Clone, Copy, PartialEq, Eq)]
11pub enum TransactionStatus {
12    Success,
13    Failure,
14}
15
16impl TransactionStatus {
17    pub fn from_u8(val: u8) -> Result<Self> {
18        match val {
19            1 => Ok(Self::Success),
20            0 => Ok(Self::Failure),
21            _ => Err(Error::UnknownTransactionStatus(val.to_string())),
22        }
23    }
24
25    pub fn to_u8(&self) -> u8 {
26        match self {
27            Self::Success => 1,
28            Self::Failure => 0,
29        }
30    }
31}
32
33impl FromStr for TransactionStatus {
34    type Err = Error;
35
36    fn from_str(s: &str) -> Result<Self> {
37        match s {
38            "0x1" => Ok(Self::Success),
39            "0x0" => Ok(Self::Failure),
40            _ => Err(Error::UnknownTransactionStatus(s.to_owned())),
41        }
42    }
43}
44
45impl TransactionStatus {
46    pub fn as_str(&self) -> &'static str {
47        match self {
48            Self::Success => "0x1",
49            Self::Failure => "0x0",
50        }
51    }
52}
53
54struct TransactionStatusVisitor;
55
56impl Visitor<'_> for TransactionStatusVisitor {
57    type Value = TransactionStatus;
58
59    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
60        formatter.write_str("hex string for transaction status")
61    }
62
63    fn visit_str<E>(self, value: &str) -> StdResult<Self::Value, E>
64    where
65        E: de::Error,
66    {
67        TransactionStatus::from_str(value).map_err(|e| E::custom(e.to_string()))
68    }
69}
70
71impl<'de> Deserialize<'de> for TransactionStatus {
72    fn deserialize<D>(deserializer: D) -> StdResult<Self, D::Error>
73    where
74        D: Deserializer<'de>,
75    {
76        deserializer.deserialize_str(TransactionStatusVisitor)
77    }
78}
79
80impl Serialize for TransactionStatus {
81    fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
82    where
83        S: Serializer,
84    {
85        serializer.serialize_str(self.as_str())
86    }
87}
88
89impl Hex for TransactionStatus {
90    fn encode_hex(&self) -> String {
91        self.as_str().to_owned()
92    }
93
94    fn decode_hex(hex: &str) -> Result<Self> {
95        Self::from_str(hex)
96    }
97}
98
99impl fmt::Debug for TransactionStatus {
100    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101        write!(f, "TransactionStatus({})", self.encode_hex())
102    }
103}
104
105#[cfg(test)]
106mod tests {
107    use super::TransactionStatus;
108    use serde_test::{assert_de_tokens, assert_tokens, Token};
109
110    #[test]
111    fn test_serde() {
112        assert_tokens(&TransactionStatus::Success, &[Token::Str("0x1")]);
113        assert_tokens(&TransactionStatus::Failure, &[Token::Str("0x0")]);
114    }
115
116    #[test]
117    #[should_panic]
118    fn test_de_unknown() {
119        assert_de_tokens(&TransactionStatus::Success, &[Token::Str("0x3")]);
120    }
121}