Skip to main content

polyoxide_data/api/
open_interest.rs

1use polyoxide_core::RequestError;
2use reqwest::Client;
3use url::Url;
4
5use crate::{error::DataApiError, types::OpenInterest};
6
7/// OpenInterest namespace for open interest operations
8#[derive(Clone)]
9pub struct OpenInterestApi {
10    pub(crate) client: Client,
11    pub(crate) base_url: Url,
12}
13
14impl OpenInterestApi {
15    /// Get open interest for markets
16    pub fn get(&self) -> GetOpenInterest {
17        GetOpenInterest {
18            client: self.client.clone(),
19            base_url: self.base_url.clone(),
20            markets: None,
21        }
22    }
23}
24
25/// Request builder for getting open interest
26pub struct GetOpenInterest {
27    client: Client,
28    base_url: Url,
29    markets: Option<Vec<String>>,
30}
31
32impl GetOpenInterest {
33    /// Filter by specific market condition IDs
34    pub fn market(mut self, condition_ids: impl IntoIterator<Item = impl ToString>) -> Self {
35        let ids: Vec<String> = condition_ids.into_iter().map(|s| s.to_string()).collect();
36        if !ids.is_empty() {
37            self.markets = Some(ids);
38        }
39        self
40    }
41
42    /// Execute the request
43    pub async fn send(self) -> Result<Vec<OpenInterest>, DataApiError> {
44        let url = self.base_url.join("/oi")?;
45        let mut request = self.client.get(url);
46
47        if let Some(markets) = self.markets {
48            request = request.query(&[("market", markets.join(","))]);
49        }
50
51        let response = request.send().await?;
52        let status = response.status();
53
54        if !status.is_success() {
55            return Err(DataApiError::from_response(response).await);
56        }
57
58        let oi: Vec<OpenInterest> = response.json().await?;
59        Ok(oi)
60    }
61}