ig_client/application/services/
account_service.rs1use async_trait::async_trait;
2use reqwest::Method;
3use std::sync::Arc;
4use tracing::{debug, info};
5
6use crate::{
7 application::models::account::{
8 AccountActivity, AccountInfo, Positions, TransactionHistory, WorkingOrders,
9 },
10 config::Config,
11 error::AppError,
12 session::interface::IgSession,
13 transport::http_client::IgHttpClient,
14};
15
16#[async_trait]
18pub trait AccountService: Send + Sync {
19 async fn get_accounts(&self, session: &IgSession) -> Result<AccountInfo, AppError>;
21
22 async fn get_positions(&self, session: &IgSession) -> Result<Positions, AppError>;
24
25 async fn get_working_orders(&self, session: &IgSession) -> Result<WorkingOrders, AppError>;
27
28 async fn get_activity(
30 &self,
31 session: &IgSession,
32 from: &str,
33 to: &str,
34 ) -> Result<AccountActivity, AppError>;
35
36 async fn get_transactions(
38 &self,
39 session: &IgSession,
40 from: &str,
41 to: &str,
42 page_size: u32,
43 page_number: u32,
44 ) -> Result<TransactionHistory, AppError>;
45}
46
47pub struct AccountServiceImpl<T: IgHttpClient> {
49 config: Arc<Config>,
50 client: Arc<T>,
51}
52
53impl<T: IgHttpClient> AccountServiceImpl<T> {
54 pub fn new(config: Arc<Config>, client: Arc<T>) -> Self {
56 Self { config, client }
57 }
58
59 pub fn get_config(&self) -> Arc<Config> {
64 self.config.clone()
65 }
66
67 pub fn set_config(&mut self, config: Arc<Config>) {
72 self.config = config;
73 }
74}
75
76#[async_trait]
77impl<T: IgHttpClient + 'static> AccountService for AccountServiceImpl<T> {
78 async fn get_accounts(&self, session: &IgSession) -> Result<AccountInfo, AppError> {
79 info!("Getting account information");
80
81 let result = self
82 .client
83 .request::<(), AccountInfo>(Method::GET, "accounts", session, None, "1")
84 .await?;
85
86 debug!(
87 "Account information obtained: {} accounts",
88 result.accounts.len()
89 );
90 Ok(result)
91 }
92
93 async fn get_positions(&self, session: &IgSession) -> Result<Positions, AppError> {
94 info!("Getting open positions");
95
96 let result = self
97 .client
98 .request::<(), Positions>(Method::GET, "positions", session, None, "2")
99 .await?;
100
101 debug!("Positions obtained: {} positions", result.positions.len());
102 Ok(result)
103 }
104
105 async fn get_working_orders(&self, session: &IgSession) -> Result<WorkingOrders, AppError> {
106 info!("Getting working orders");
107
108 let result = self
109 .client
110 .request::<(), WorkingOrders>(Method::GET, "workingorders", session, None, "2")
111 .await?;
112
113 debug!(
114 "Working orders obtained: {} orders",
115 result.working_orders.len()
116 );
117 Ok(result)
118 }
119
120 async fn get_activity(
121 &self,
122 session: &IgSession,
123 from: &str,
124 to: &str,
125 ) -> Result<AccountActivity, AppError> {
126 let path = format!("history/activity?from={}&to={}", from, to);
127 info!("Getting account activity");
128
129 let result = self
130 .client
131 .request::<(), AccountActivity>(Method::GET, &path, session, None, "3")
132 .await?;
133
134 debug!(
135 "Account activity obtained: {} activities",
136 result.activities.len()
137 );
138 Ok(result)
139 }
140
141 async fn get_transactions(
142 &self,
143 session: &IgSession,
144 from: &str,
145 to: &str,
146 page_size: u32,
147 page_number: u32,
148 ) -> Result<TransactionHistory, AppError> {
149 let path = format!(
150 "history/transactions?from={}&to={}&pageSize={}&pageNumber={}",
151 from, to, page_size, page_number
152 );
153 info!("Getting transaction history");
154
155 let result = self
156 .client
157 .request::<(), TransactionHistory>(Method::GET, &path, session, None, "2")
158 .await?;
159
160 debug!(
161 "Transaction history obtained: {} transactions",
162 result.transactions.len()
163 );
164 Ok(result)
165 }
166}