1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
use crate::api::{Client, Config, Datamaxi, Result};
pub use crate::models::{CandleOptions, SymbolsOptions};
use crate::models::{CandleResponse, SymbolsResponse};
use std::collections::HashMap;

/// Provides methods for retrieving CEX candle data and related information.
#[derive(Clone)]
pub struct Candle {
    pub client: Client,
}

impl Candle {
    /// Retrieves candle data for a specified exchange and symbol. Additional parameters can be
    /// provided to filter and sort the results. The response will contain an array of candle data
    /// objects, each representing a single candle with open, high, low, close, and volume values.
    pub fn get<E, S>(
        &self,
        exchange: E,
        symbol: S,
        options: CandleOptions,
    ) -> Result<CandleResponse>
    where
        E: Into<String>,
        S: Into<String>,
    {
        let mut parameters = HashMap::new();

        // required
        parameters.insert("exchange".to_string(), exchange.into());
        parameters.insert("symbol".to_string(), symbol.into());

        // optional
        parameters.extend(
            [
                options
                    .market
                    .map(|market| ("market".to_string(), market.to_string())),
                options
                    .interval
                    .map(|interval| ("interval".to_string(), interval.to_string())),
                options
                    .page
                    .map(|page| ("page".to_string(), page.to_string())),
                options
                    .limit
                    .map(|limit| ("limit".to_string(), limit.to_string())),
                options
                    .from
                    .map(|from| ("from".to_string(), from.to_string())),
                options.to.map(|to| ("to".to_string(), to.to_string())),
                options
                    .sort
                    .map(|sort| ("sort".to_string(), sort.to_string())),
            ]
            .into_iter()
            .flatten(),
        );

        self.client.get("/cex/candle", Some(parameters))
    }

    /// Retrieves a list of supported exchanges for candle data. The market parameter can be used
    /// to filter the results by market.
    pub fn exchanges<M>(&self, market: M) -> Result<Vec<String>>
    where
        M: Into<String>,
    {
        let mut parameters = HashMap::new();

        // required
        parameters.insert("market".to_string(), market.into());

        self.client.get("/cex/candle/exchanges", Some(parameters))
    }

    /// Retrieves a list of supported symbols for candle data. The exchange parameter is required,
    /// and the market parameter can be used to filter the results by market.
    pub fn symbols<E>(&self, exchange: E, options: SymbolsOptions) -> Result<Vec<SymbolsResponse>>
    where
        E: Into<String>,
    {
        let mut parameters = HashMap::new();

        // required
        parameters.insert("exchange".to_string(), exchange.into());

        // optional
        if let Some(market) = options.market {
            parameters.insert("market".to_string(), market);
        }

        self.client.get("/cex/candle/symbols", Some(parameters))
    }

    /// Retrieves a list of supported candle intervals.
    pub fn intervals(&self) -> Result<Vec<String>> {
        self.client.get("/cex/candle/intervals", None)
    }
}

/// Implements the `Datamaxi` trait for `Candle`, providing methods
/// to create new instances of `Candle` with or without a custom base URL.
impl Datamaxi for Candle {
    /// Creates a new `Candle` instance with the default base URL.
    ///
    /// # Parameters
    /// - `api_key`: A `String` representing the API key used for authentication in API requests.
    ///
    /// # Returns
    /// A new `Candle` instance configured with the default base URL and the provided `api_key`.
    ///
    /// # Example
    /// ```rust
    /// use crate::datamaxi::api::Datamaxi;
    /// let candle = datamaxi::cex::Candle::new("my_api_key".to_string());
    /// ```
    fn new(api_key: String) -> Candle {
        let config = Config {
            base_url: None, // Default base URL will be used
            api_key,        // Provided API key
        };
        Candle {
            client: Client::new(config), // Create a new client with the given config
        }
    }

    /// Creates a new `Candle` instance with a custom base URL.
    ///
    /// # Parameters
    /// - `api_key`: A `String` representing the API key used for authentication in API requests.
    /// - `base_url`: A `String` representing the custom base URL for API requests.
    ///
    /// # Returns
    /// A new `Candle` instance configured with the specified `base_url` and `api_key`.
    ///
    /// # Example
    /// ```rust
    /// use crate::datamaxi::api::Datamaxi;
    /// let candle = datamaxi::cex::Candle::new_with_base_url("my_api_key".to_string(), "https://custom-api.example.com".to_string());
    /// ```
    fn new_with_base_url(api_key: String, base_url: String) -> Candle {
        let config = Config {
            base_url: Some(base_url), // Use the provided custom base URL
            api_key,                  // Provided API key
        };
        Candle {
            client: Client::new(config), // Create a new client with the given config
        }
    }
}