ftx/rest/model/
subaccounts.rs

1use super::{
2    common::{Coin, Id},
3    Request,
4};
5use chrono::{DateTime, Utc};
6use http::Method;
7use rust_decimal::Decimal;
8use serde::{Deserialize, Serialize};
9use std::borrow::Cow;
10use std::convert::TryFrom;
11use std::fmt::Debug;
12
13#[derive(Clone, Debug, Deserialize, Serialize)]
14#[serde(rename_all = "camelCase")]
15pub struct Subaccount {
16    pub nickname: String,
17    pub deletable: bool,
18    pub editable: bool,
19    pub competition: bool,
20}
21
22#[derive(Debug, Clone, Serialize, Default)]
23pub struct GetSubaccounts {}
24
25impl Request for GetSubaccounts {
26    const METHOD: Method = Method::GET;
27    const PATH: &'static str = "/subaccounts";
28    const AUTH: bool = true;
29
30    type Response = Vec<Subaccount>;
31}
32
33#[derive(Debug, Clone, Serialize)]
34pub struct CreateSubaccount {
35    pub nickname: String,
36}
37
38impl CreateSubaccount {
39    pub fn new(nickname: &str) -> Self {
40        Self {
41            nickname: nickname.to_string(),
42        }
43    }
44}
45
46#[derive(Clone, Debug, Deserialize, Serialize)]
47#[serde(rename_all = "camelCase")]
48pub struct Create {
49    pub nickname: String,
50    pub deletable: bool,
51    pub editable: bool,
52}
53
54impl Request for CreateSubaccount {
55    const METHOD: Method = Method::POST;
56    const PATH: &'static str = "/subaccounts";
57    const AUTH: bool = true;
58
59    type Response = Create;
60}
61
62#[derive(Debug, Clone, Serialize, Default)]
63#[serde(rename_all = "camelCase")]
64pub struct ChangeSubaccountName {
65    pub nickname: String,
66    pub new_nickname: String,
67}
68
69impl ChangeSubaccountName {
70    pub fn new(nickname: &str, new_nickname: &str) -> Self {
71        Self {
72            nickname: nickname.into(),
73            new_nickname: new_nickname.into(),
74        }
75    }
76}
77
78impl Request for ChangeSubaccountName {
79    const METHOD: Method = Method::POST;
80    const PATH: &'static str = "/subaccounts/update_name";
81    const AUTH: bool = true;
82
83    type Response = ();
84}
85
86#[derive(Debug, Clone, Serialize, Default)]
87#[serde(rename_all = "camelCase")]
88pub struct DeleteSubaccount {
89    pub nickname: String,
90}
91
92impl DeleteSubaccount {
93    pub fn new(nickname: &str) -> Self {
94        Self {
95            nickname: nickname.into(),
96        }
97    }
98}
99
100impl Request for DeleteSubaccount {
101    const METHOD: Method = Method::DELETE;
102    const PATH: &'static str = "/subaccounts";
103    const AUTH: bool = true;
104
105    type Response = ();
106}
107
108#[derive(Clone, Debug, Deserialize)]
109#[serde(rename_all = "camelCase")]
110pub struct Balance {
111    pub coin: Coin,
112    pub free: Decimal,
113    pub total: Decimal,
114    pub spot_borrow: Decimal,
115    pub available_without_borrow: Decimal,
116}
117
118#[derive(Debug, Clone, Serialize, Default)]
119#[serde(rename_all = "camelCase")]
120pub struct GetSubaccountBalances {
121    #[serde(skip_serializing)]
122    pub nickname: String,
123}
124
125impl GetSubaccountBalances {
126    pub fn new(nickname: &str) -> Self {
127        Self {
128            nickname: nickname.into(),
129        }
130    }
131}
132
133impl Request for GetSubaccountBalances {
134    const METHOD: Method = Method::GET;
135    const PATH: &'static str = "/subaccounts/{}/balances";
136    const AUTH: bool = true;
137
138    type Response = Vec<Balance>;
139
140    fn path(&self) -> Cow<'_, str> {
141        Cow::Owned(format!("/subaccounts/{}/balances", self.nickname))
142    }
143}
144
145#[derive(Clone, Debug, Deserialize)]
146#[serde(rename_all = "camelCase")]
147pub struct Transfer {
148    pub id: Id,
149    pub coin: Coin,
150    pub size: Decimal,
151    pub time: DateTime<Utc>,
152    pub notes: String,
153}
154
155#[derive(Debug, Clone, Serialize, Default)]
156#[serde(rename_all = "camelCase")]
157pub struct TransferBetweenSubaccounts {
158    pub coin: String,
159    pub size: Decimal,
160    pub source: String,
161    pub destination: String,
162}
163
164impl TransferBetweenSubaccounts {
165    pub fn new<S>(coin: &str, size: S, source: &str, destination: &str) -> Self
166    where
167        Decimal: TryFrom<S>,
168        <Decimal as TryFrom<S>>::Error: Debug,
169    {
170        Self {
171            coin: coin.into(),
172            size: Decimal::try_from(size).unwrap(),
173            source: source.into(),
174            destination: destination.into(),
175        }
176    }
177}
178
179impl Request for TransferBetweenSubaccounts {
180    const METHOD: Method = Method::POST;
181    const PATH: &'static str = "/subaccounts/transfer";
182    const AUTH: bool = true;
183
184    type Response = Transfer;
185}