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}