waves_rust/model/
transaction_status.rs

1use crate::error::{Error, Result};
2use crate::model::{ApplicationStatus, Id};
3use crate::util::JsonDeserializer;
4use serde_json::Value;
5
6#[derive(Clone, Eq, PartialEq, Debug)]
7pub struct TransactionStatus {
8    id: Id,
9    status: Status,
10    app_status: Option<ApplicationStatus>,
11    height: u32,
12    confirmation: u32,
13}
14
15impl TransactionStatus {
16    pub fn new(
17        id: Id,
18        status: Status,
19        app_status: Option<ApplicationStatus>,
20        height: u32,
21        confirmation: u32,
22    ) -> Self {
23        Self {
24            id,
25            status,
26            app_status,
27            height,
28            confirmation,
29        }
30    }
31
32    pub fn id(&self) -> Id {
33        self.id.clone()
34    }
35
36    pub fn status(&self) -> Status {
37        self.status
38    }
39
40    pub fn app_status(&self) -> Option<ApplicationStatus> {
41        self.app_status
42    }
43
44    pub fn height(&self) -> u32 {
45        self.height
46    }
47
48    pub fn confirmation(&self) -> u32 {
49        self.confirmation
50    }
51}
52
53impl TryFrom<&Value> for TransactionStatus {
54    type Error = Error;
55
56    fn try_from(value: &Value) -> Result<Self> {
57        let status = JsonDeserializer::safe_to_string_from_field(value, "status")?;
58        let tx_status = match status.as_str() {
59            "not_found" => Status::NotFound,
60            "unconfirmed" => Status::Unconfirmed,
61            "confirmed" => Status::Confirmed,
62            _ => Status::Unknown,
63        };
64
65        let id = JsonDeserializer::safe_to_string_from_field(value, "id")?;
66
67        let application_status = match value["applicationStatus"].as_str() {
68            Some(status) => match status {
69                "succeeded" => Some(ApplicationStatus::Succeed),
70                "script_execution_failed" => Some(ApplicationStatus::ScriptExecutionFailed),
71                &_ => Some(ApplicationStatus::Unknown),
72            },
73            None => None,
74        };
75
76        let height = JsonDeserializer::safe_to_int_from_field(value, "height")?;
77        let confirmations = JsonDeserializer::safe_to_int_from_field(value, "confirmations")?;
78
79        Ok(TransactionStatus {
80            id: Id::from_string(&id)?,
81            status: tx_status,
82            app_status: application_status,
83            height: height as u32,
84            confirmation: confirmations as u32,
85        })
86    }
87}
88
89#[derive(Debug, Clone, Copy, Eq, PartialEq)]
90pub enum Status {
91    NotFound,
92    Unconfirmed,
93    Confirmed,
94    Unknown,
95}
96
97#[cfg(test)]
98mod tests {
99    use crate::error::Result;
100    use crate::model::{ApplicationStatus, ByteString, Status, TransactionStatus};
101
102    use serde_json::Value;
103    use std::borrow::Borrow;
104    use std::fs;
105
106    #[test]
107    fn test_json_to_transaction_status() -> Result<()> {
108        let data = fs::read_to_string("./tests/resources/transaction_status_rs.json")
109            .expect("Unable to read file");
110        let json: Value = serde_json::from_str(&data).expect("failed to generate json from str");
111
112        let transaction_status: TransactionStatus = json.borrow().try_into()?;
113
114        assert_eq!(transaction_status.status(), Status::Confirmed);
115        assert_eq!(transaction_status.height(), 2217333);
116        assert_eq!(transaction_status.confirmation(), 14051);
117        assert_eq!(
118            transaction_status.app_status().unwrap(),
119            ApplicationStatus::Succeed
120        );
121        assert_eq!(
122            transaction_status.id().encoded(),
123            "4XFVLLMBjBMPwGivgyLhw374kViANoToLAYUdEXWLsBJ"
124        );
125        Ok(())
126    }
127}