ig_client/application/services/
market_service.rs1use crate::application::services::MarketService;
2use crate::{
3 application::models::market::{HistoricalPricesResponse, MarketDetails, MarketSearchResult},
4 config::Config,
5 error::AppError,
6 session::interface::IgSession,
7 transport::http_client::IgHttpClient,
8};
9use async_trait::async_trait;
10use reqwest::Method;
11use std::sync::Arc;
12use tracing::{debug, info};
13
14pub struct MarketServiceImpl<T: IgHttpClient> {
16 config: Arc<Config>,
17 client: Arc<T>,
18}
19
20impl<T: IgHttpClient> MarketServiceImpl<T> {
21 pub fn new(config: Arc<Config>, client: Arc<T>) -> Self {
23 Self { config, client }
24 }
25
26 pub fn get_config(&self) -> &Config {
31 &self.config
32 }
33
34 pub fn set_config(&mut self, config: Arc<Config>) {
39 self.config = config;
40 }
41}
42
43#[async_trait]
44impl<T: IgHttpClient + 'static> MarketService for MarketServiceImpl<T> {
45 async fn search_markets(
46 &self,
47 session: &IgSession,
48 search_term: &str,
49 ) -> Result<MarketSearchResult, AppError> {
50 let path = format!("markets?searchTerm={}", search_term);
51 info!("Searching markets with term: {}", search_term);
52
53 let result = self
54 .client
55 .request::<(), MarketSearchResult>(Method::GET, &path, session, None, "1")
56 .await?;
57
58 debug!("{} markets found", result.markets.len());
59 Ok(result)
60 }
61
62 async fn get_market_details(
63 &self,
64 session: &IgSession,
65 epic: &str,
66 ) -> Result<MarketDetails, AppError> {
67 let path = format!("markets/{}", epic);
68 info!("Getting market details: {}", epic);
69
70 let result = self
71 .client
72 .request::<(), MarketDetails>(Method::GET, &path, session, None, "3")
73 .await?;
74
75 debug!("Market details obtained for: {}", epic);
76 Ok(result)
77 }
78
79 async fn get_historical_prices(
80 &self,
81 session: &IgSession,
82 epic: &str,
83 resolution: &str,
84 from: &str,
85 to: &str,
86 ) -> Result<HistoricalPricesResponse, AppError> {
87 let path = format!("prices/{}/{}?from={}&to={}", epic, resolution, from, to);
88 info!("Getting historical prices for: {}", epic);
89
90 let result = self
91 .client
92 .request::<(), HistoricalPricesResponse>(Method::GET, &path, session, None, "3")
93 .await?;
94
95 debug!("Historical prices obtained for: {}", epic);
96 Ok(result)
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103 use crate::config::Config;
104 use crate::transport::http_client::IgHttpClientImpl;
105 use std::sync::Arc;
106
107 #[test]
108 fn test_get_and_set_config() {
109 let config = Arc::new(Config::new());
110 let client = Arc::new(IgHttpClientImpl::new(config.clone()));
111 let mut service = MarketServiceImpl::new(config.clone(), client.clone());
112 assert!(std::ptr::eq(service.get_config(), &*config));
113 let new_cfg = Arc::new(Config::default());
114 service.set_config(new_cfg.clone());
115 assert!(std::ptr::eq(service.get_config(), &*new_cfg));
116 }
117}