deribit_http/model/response/
transfer.rs1use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
12#[serde(rename_all = "snake_case")]
13pub enum InternalTransferState {
14 #[default]
16 Prepared,
17 Confirmed,
19 Cancelled,
21 WaitingForAdmin,
23}
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
27#[serde(rename_all = "snake_case")]
28pub enum TransferDirection {
29 #[default]
31 Payment,
32 Income,
34}
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
38#[serde(rename_all = "snake_case")]
39pub enum InternalTransferType {
40 #[default]
42 Subaccount,
43 User,
45}
46
47#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
52pub struct InternalTransfer {
53 pub id: i64,
55 pub currency: String,
57 pub amount: f64,
59 pub direction: TransferDirection,
61 pub other_side: String,
63 pub state: InternalTransferState,
65 #[serde(rename = "type")]
67 pub transfer_type: InternalTransferType,
68 pub created_timestamp: i64,
70 pub updated_timestamp: i64,
72}
73
74impl InternalTransfer {
75 #[must_use]
77 pub fn is_confirmed(&self) -> bool {
78 self.state == InternalTransferState::Confirmed
79 }
80
81 #[must_use]
83 pub fn is_cancelled(&self) -> bool {
84 self.state == InternalTransferState::Cancelled
85 }
86
87 #[must_use]
89 pub fn is_pending(&self) -> bool {
90 matches!(
91 self.state,
92 InternalTransferState::Prepared | InternalTransferState::WaitingForAdmin
93 )
94 }
95
96 #[must_use]
98 pub fn is_payment(&self) -> bool {
99 self.direction == TransferDirection::Payment
100 }
101
102 #[must_use]
104 pub fn is_income(&self) -> bool {
105 self.direction == TransferDirection::Income
106 }
107}
108
109#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
113pub struct TransfersResponse {
114 pub count: u32,
116 pub data: Vec<InternalTransfer>,
118}
119
120impl TransfersResponse {
121 #[must_use]
123 pub fn is_empty(&self) -> bool {
124 self.data.is_empty()
125 }
126
127 #[must_use]
129 pub fn len(&self) -> usize {
130 self.data.len()
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137
138 #[test]
139 fn test_internal_transfer_deserialization() {
140 let json = r#"{
141 "id": 2,
142 "created_timestamp": 1550579457727,
143 "updated_timestamp": 1550579457727,
144 "currency": "BTC",
145 "amount": 0.2,
146 "direction": "payment",
147 "other_side": "new_user_1_1",
148 "state": "confirmed",
149 "type": "subaccount"
150 }"#;
151
152 let transfer: InternalTransfer = serde_json::from_str(json).unwrap();
153 assert_eq!(transfer.id, 2);
154 assert_eq!(transfer.currency, "BTC");
155 assert!((transfer.amount - 0.2).abs() < f64::EPSILON);
156 assert_eq!(transfer.direction, TransferDirection::Payment);
157 assert_eq!(transfer.other_side, "new_user_1_1");
158 assert_eq!(transfer.state, InternalTransferState::Confirmed);
159 assert_eq!(transfer.transfer_type, InternalTransferType::Subaccount);
160 assert!(transfer.is_confirmed());
161 assert!(transfer.is_payment());
162 }
163
164 #[test]
165 fn test_transfers_response_deserialization() {
166 let json = r#"{
167 "count": 1,
168 "data": [{
169 "id": 2,
170 "created_timestamp": 1550579457727,
171 "updated_timestamp": 1550579457727,
172 "currency": "BTC",
173 "amount": 0.2,
174 "direction": "payment",
175 "other_side": "new_user_1_1",
176 "state": "confirmed",
177 "type": "subaccount"
178 }]
179 }"#;
180
181 let response: TransfersResponse = serde_json::from_str(json).unwrap();
182 assert_eq!(response.count, 1);
183 assert_eq!(response.len(), 1);
184 assert!(!response.is_empty());
185 }
186
187 #[test]
188 fn test_transfer_state_helpers() {
189 let mut transfer = InternalTransfer {
190 id: 1,
191 currency: "BTC".to_string(),
192 amount: 1.0,
193 direction: TransferDirection::Payment,
194 other_side: "test".to_string(),
195 state: InternalTransferState::Prepared,
196 transfer_type: InternalTransferType::Subaccount,
197 created_timestamp: 0,
198 updated_timestamp: 0,
199 };
200
201 assert!(transfer.is_pending());
202 assert!(!transfer.is_confirmed());
203 assert!(!transfer.is_cancelled());
204
205 transfer.state = InternalTransferState::Confirmed;
206 assert!(!transfer.is_pending());
207 assert!(transfer.is_confirmed());
208
209 transfer.state = InternalTransferState::Cancelled;
210 assert!(transfer.is_cancelled());
211 }
212}