midgard_rs/types/
action.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use serde_aux::prelude::*;
4use serde_with::formats::Flexible;
5use serde_with::TimestampNanoSeconds;
6
7use crate::ActionIns;
8use crate::ActionMetadata;
9use crate::ActionOuts;
10use crate::ActionType;
11
12/*
13
14*** Action Scheme ***
15
16{
17		"date": "1710385361850070696",
18		"height": "15102881",
19		"in": ActionIns,
20		"metadata": ActionMetadata,
21		"out": ActionOuts,
22		"pools": ["BSC.BNB", "BTC.BTC", ...],
23		"status": "success",
24		"type": ActionType
25}
26
27*/
28
29#[serde_with::serde_as]
30#[derive(Debug, Serialize, Deserialize, Clone, Default)]
31pub struct Action {
32	#[serde_as(as = "TimestampNanoSeconds<String, Flexible>")]
33	date: DateTime<Utc>,
34
35	#[serde(deserialize_with = "deserialize_number_from_string")]
36	height: u64,
37
38	#[serde(rename = "in")]
39	action_ins: ActionIns,
40
41	metadata: ActionMetadata,
42
43	#[serde(rename = "out")]
44	action_outs: ActionOuts,
45
46	pools: Vec<String>,
47
48	status: String,
49
50	#[serde(rename = "type")]
51	action_type: ActionType,
52}
53
54impl Action {
55	#[must_use]
56	pub const fn get_date(&self) -> &DateTime<Utc> {
57		&self.date
58	}
59
60	#[must_use]
61	pub const fn get_height(&self) -> &u64 {
62		&self.height
63	}
64
65	#[must_use]
66	pub const fn get_action_ins(&self) -> &ActionIns {
67		&self.action_ins
68	}
69
70	#[must_use]
71	pub const fn get_metadata(&self) -> &ActionMetadata {
72		&self.metadata
73	}
74
75	#[must_use]
76	pub const fn get_action_outs(&self) -> &ActionOuts {
77		&self.action_outs
78	}
79
80	#[must_use]
81	pub const fn get_pools(&self) -> &Vec<String> {
82		&self.pools
83	}
84
85	#[must_use]
86	pub const fn get_status(&self) -> &String {
87		&self.status
88	}
89
90	#[must_use]
91	pub const fn get_action_type(&self) -> &ActionType {
92		&self.action_type
93	}
94}
95
96#[cfg(test)]
97mod tests {
98	use serde_json::json;
99
100	use crate::{Action, ActionType};
101
102	#[test]
103	fn deserialize_action() {
104		let json = json!(
105		{
106				"date": "1710527743635577563",
107				"height": "15125786",
108				"in": [
109						{
110								"address": "thor15e5ssnh5zz6ahztk9q45jz9385yyv2kjndadhc",
111								"coins": [],
112								"txID": "4A552F834B261805018CABA16DFDF62F27E820409DF3A77A2FD17330E9ADCB55"
113						}
114				],
115				"metadata": {
116						"withdraw": {
117								"asymmetry": "0",
118								"basisPoints": "10000",
119								"impermanentLossProtection": "0",
120								"liquidityUnits": "-594386180",
121								"memo": "-:BNB.AVA-645:10000",
122								"networkFees": [
123										{
124												"amount": "2000000",
125												"asset": "THOR.RUNE"
126										}
127								]
128						}
129				},
130				"out": [
131						{
132								"address": "thor15e5ssnh5zz6ahztk9q45jz9385yyv2kjndadhc",
133								"coins": [
134										{
135												"amount": "1360279671",
136												"asset": "THOR.RUNE"
137										}
138								],
139								"height": "15125786",
140								"txID": ""
141						}
142				],
143				"pools": [
144						"BNB.AVA-645"
145				],
146				"status": "success",
147				"type": "withdraw"
148		});
149		let action: Action = serde_json::from_value(json).unwrap();
150		assert_eq!(action.get_date().to_rfc3339(), "2024-03-15T18:35:43.635577563+00:00");
151		assert_eq!(*action.get_height(), 15125786 as u64);
152		assert_eq!(action.get_pools(), &vec!["BNB.AVA-645".to_string()]);
153		assert_eq!(action.get_status(), "success");
154		assert_eq!(*action.get_action_type(), ActionType::Withdraw);
155	}
156}