koios_sdk/api/
epoch.rs

1use crate::{
2    error::Result,
3    models::epoch::{EpochBlockProtocol, EpochInfo, EpochParams},
4    types::{EpochNo, IncludeNextEpoch},
5    Client,
6};
7use urlencoding::encode;
8
9impl Client {
10    /// Get the epoch information, all epochs if no epoch specified
11    ///
12    /// # Arguments
13    ///
14    /// * `epoch_no` - Optional epoch number to query
15    /// * `include_next_epoch` - Whether to include information about nearing but not yet started epoch
16    ///
17    /// # Examples
18    ///
19    /// ```no_run
20    /// use koios_sdk::{Client, types::{EpochNo, IncludeNextEpoch}};
21    ///
22    /// #[tokio::main]
23    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
24    ///     let client = Client::new()?;
25    ///     
26    ///     // Get all epochs
27    ///     let all_epochs = client.get_epoch_info(None, None).await?;
28    ///     
29    ///     // Get specific epoch with next epoch info
30    ///     let epoch = client.get_epoch_info(
31    ///         Some(EpochNo::new("320")),
32    ///         Some(IncludeNextEpoch::new(true))
33    ///     ).await?;
34    ///     
35    ///     Ok(())
36    /// }
37    /// ```
38    pub async fn get_epoch_info(
39        &self,
40        epoch_no: Option<EpochNo>,
41        include_next_epoch: Option<IncludeNextEpoch>,
42    ) -> Result<Vec<EpochInfo>> {
43        use urlencoding::encode;
44
45        let mut query_params = vec![];
46
47        if let Some(epoch) = epoch_no {
48            query_params.push(("_epoch_no", epoch.0));
49        }
50
51        if let Some(include_next) = include_next_epoch {
52            query_params.push(("_include_next_epoch", include_next.0.to_string()));
53        }
54
55        let query_string = if !query_params.is_empty() {
56            let encoded_params: Vec<String> = query_params
57                .into_iter()
58                .map(|(k, v)| format!("{}={}", encode(k), encode(&v)))
59                .collect();
60            format!("?{}", encoded_params.join("&"))
61        } else {
62            String::new()
63        };
64
65        self.get(&format!("/epoch_info{}", query_string)).await
66    }
67
68    /// Get the protocol parameters for specific epoch, returns information about all epochs if no epoch specified
69    ///
70    /// # Arguments
71    ///
72    /// * `epoch_no` - Optional epoch number to query
73    ///
74    /// # Examples
75    ///
76    /// ```no_run
77    /// use koios_sdk::{Client, types::EpochNo};
78    ///
79    /// #[tokio::main]
80    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
81    ///     let client = Client::new()?;
82    ///     
83    ///     // Get all epochs' parameters
84    ///     let all_params = client.get_epoch_params(None).await?;
85    ///     
86    ///     // Get specific epoch parameters
87    ///     let params = client.get_epoch_params(Some(EpochNo::new("320"))).await?;
88    ///     
89    ///     Ok(())
90    /// }
91    /// ```
92    pub async fn get_epoch_params(&self, epoch_no: Option<EpochNo>) -> Result<Vec<EpochParams>> {
93        let endpoint = match epoch_no {
94            Some(epoch) => format!("/epoch_params?_epoch_no={}", encode(epoch.value())),
95            None => "/epoch_params".to_string(),
96        };
97        self.get(&endpoint).await
98    }
99
100    /// Get block protocol versions for specific epoch, returns information about all epochs if no epoch specified
101    ///
102    /// # Arguments
103    ///
104    /// * `epoch_no` - Optional epoch number to query
105    ///
106    /// # Examples
107    ///
108    /// ```no_run
109    /// use koios_sdk::{Client, types::EpochNo};
110    ///
111    /// #[tokio::main]
112    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
113    ///     let client = Client::new()?;
114    ///     
115    ///     // Get all epochs' block protocols
116    ///     let all_protocols = client.get_epoch_block_protocols(None).await?;
117    ///     
118    ///     // Get specific epoch block protocols
119    ///     let protocols = client.get_epoch_block_protocols(Some(EpochNo::new("320"))).await?;
120    ///     
121    ///     Ok(())
122    /// }
123    /// ```
124    pub async fn get_epoch_block_protocols(
125        &self,
126        epoch_no: Option<EpochNo>,
127    ) -> Result<Vec<EpochBlockProtocol>> {
128        let endpoint = match epoch_no {
129            Some(epoch) => format!("/epoch_block_protocols?_epoch_no={}", encode(epoch.value())),
130            None => "/epoch_block_protocols".to_string(),
131        };
132        self.get(&endpoint).await
133    }
134}
135
136#[cfg(test)]
137mod tests {
138    use super::*;
139    use tokio;
140
141    #[tokio::test]
142    async fn test_get_epoch_info() {
143        let client = Client::new().unwrap();
144
145        // Test without parameters
146        let result = client.get_epoch_info(None, None).await;
147        assert!(result.is_ok());
148
149        // Test with epoch number
150        let result = client.get_epoch_info(Some(EpochNo::new("320")), None).await;
151        assert!(result.is_ok());
152
153        // Test with include_next_epoch
154        let result = client
155            .get_epoch_info(None, Some(IncludeNextEpoch::new(true)))
156            .await;
157        assert!(result.is_ok());
158
159        // Test with both parameters
160        let result = client
161            .get_epoch_info(Some(EpochNo::new("320")), Some(IncludeNextEpoch::new(true)))
162            .await;
163        assert!(result.is_ok());
164    }
165
166    #[tokio::test]
167    async fn test_get_epoch_params() {
168        let client = Client::new().unwrap();
169
170        // Test without parameters
171        let result = client.get_epoch_params(None).await;
172        assert!(result.is_ok());
173
174        // Test with epoch number
175        let result = client.get_epoch_params(Some(EpochNo::new("320"))).await;
176        assert!(result.is_ok());
177    }
178
179    #[tokio::test]
180    async fn test_get_epoch_block_protocols() {
181        let client = Client::new().unwrap();
182
183        // Test without parameters
184        let result = client.get_epoch_block_protocols(None).await;
185        assert!(result.is_ok());
186
187        // Test with epoch number
188        let result = client
189            .get_epoch_block_protocols(Some(EpochNo::new("320")))
190            .await;
191        assert!(result.is_ok());
192    }
193}