Skip to main content

polyoxide_gamma/api/
events.rs

1use polyoxide_core::{HttpClient, QueryBuilder, Request};
2
3use crate::{error::GammaError, types::Event};
4
5/// Events namespace for event-related operations
6#[derive(Clone)]
7pub struct Events {
8    pub(crate) http_client: HttpClient,
9}
10
11impl Events {
12    /// List events with optional filtering
13    pub fn list(&self) -> ListEvents {
14        ListEvents {
15            request: Request::new(self.http_client.clone(), "/events"),
16        }
17    }
18
19    /// Get an event by ID
20    pub fn get(&self, id: impl Into<String>) -> Request<Event, GammaError> {
21        Request::new(
22            self.http_client.clone(),
23            format!("/events/{}", urlencoding::encode(&id.into())),
24        )
25    }
26
27    /// Get an event by slug
28    pub fn get_by_slug(&self, slug: impl Into<String>) -> Request<Event, GammaError> {
29        Request::new(
30            self.http_client.clone(),
31            format!("/events/slug/{}", urlencoding::encode(&slug.into())),
32        )
33    }
34
35    /// Get related events by slug
36    pub fn get_related_by_slug(&self, slug: impl Into<String>) -> Request<Vec<Event>, GammaError> {
37        Request::new(
38            self.http_client.clone(),
39            format!("/events/slug/{}/related", urlencoding::encode(&slug.into())),
40        )
41    }
42}
43
44/// Request builder for listing events
45pub struct ListEvents {
46    request: Request<Vec<Event>, GammaError>,
47}
48
49impl ListEvents {
50    /// Set maximum number of results (minimum: 0)
51    pub fn limit(mut self, limit: u32) -> Self {
52        self.request = self.request.query("limit", limit);
53        self
54    }
55
56    /// Set pagination offset (minimum: 0)
57    pub fn offset(mut self, offset: u32) -> Self {
58        self.request = self.request.query("offset", offset);
59        self
60    }
61
62    /// Set order fields (comma-separated list)
63    pub fn order(mut self, order: impl Into<String>) -> Self {
64        self.request = self.request.query("order", order.into());
65        self
66    }
67
68    /// Set sort direction
69    pub fn ascending(mut self, ascending: bool) -> Self {
70        self.request = self.request.query("ascending", ascending);
71        self
72    }
73
74    /// Filter by specific event IDs
75    pub fn id(mut self, ids: impl IntoIterator<Item = i64>) -> Self {
76        self.request = self.request.query_many("id", ids);
77        self
78    }
79
80    /// Filter by tag identifier
81    pub fn tag_id(mut self, tag_id: i64) -> Self {
82        self.request = self.request.query("tag_id", tag_id);
83        self
84    }
85
86    /// Exclude events with specified tag IDs
87    pub fn exclude_tag_id(mut self, tag_ids: impl IntoIterator<Item = i64>) -> Self {
88        self.request = self.request.query_many("exclude_tag_id", tag_ids);
89        self
90    }
91
92    /// Filter by event slugs
93    pub fn slug(mut self, slugs: impl IntoIterator<Item = impl ToString>) -> Self {
94        self.request = self.request.query_many("slug", slugs);
95        self
96    }
97
98    /// Filter by tag slug
99    pub fn tag_slug(mut self, slug: impl Into<String>) -> Self {
100        self.request = self.request.query("tag_slug", slug.into());
101        self
102    }
103
104    /// Include related tags in response
105    pub fn related_tags(mut self, include: bool) -> Self {
106        self.request = self.request.query("related_tags", include);
107        self
108    }
109
110    /// Filter active events only
111    pub fn active(mut self, active: bool) -> Self {
112        self.request = self.request.query("active", active);
113        self
114    }
115
116    /// Filter archived events
117    pub fn archived(mut self, archived: bool) -> Self {
118        self.request = self.request.query("archived", archived);
119        self
120    }
121
122    /// Filter featured events
123    pub fn featured(mut self, featured: bool) -> Self {
124        self.request = self.request.query("featured", featured);
125        self
126    }
127
128    /// Filter create-your-own-market events
129    pub fn cyom(mut self, cyom: bool) -> Self {
130        self.request = self.request.query("cyom", cyom);
131        self
132    }
133
134    /// Include chat data in response
135    pub fn include_chat(mut self, include: bool) -> Self {
136        self.request = self.request.query("include_chat", include);
137        self
138    }
139
140    /// Include template data
141    pub fn include_template(mut self, include: bool) -> Self {
142        self.request = self.request.query("include_template", include);
143        self
144    }
145
146    /// Filter by recurrence pattern
147    pub fn recurrence(mut self, recurrence: impl Into<String>) -> Self {
148        self.request = self.request.query("recurrence", recurrence.into());
149        self
150    }
151
152    /// Filter closed events
153    pub fn closed(mut self, closed: bool) -> Self {
154        self.request = self.request.query("closed", closed);
155        self
156    }
157
158    /// Set minimum liquidity threshold
159    pub fn liquidity_min(mut self, min: f64) -> Self {
160        self.request = self.request.query("liquidity_min", min);
161        self
162    }
163
164    /// Set maximum liquidity threshold
165    pub fn liquidity_max(mut self, max: f64) -> Self {
166        self.request = self.request.query("liquidity_max", max);
167        self
168    }
169
170    /// Set minimum trading volume
171    pub fn volume_min(mut self, min: f64) -> Self {
172        self.request = self.request.query("volume_min", min);
173        self
174    }
175
176    /// Set maximum trading volume
177    pub fn volume_max(mut self, max: f64) -> Self {
178        self.request = self.request.query("volume_max", max);
179        self
180    }
181
182    /// Set earliest start date (ISO 8601 format)
183    pub fn start_date_min(mut self, date: impl Into<String>) -> Self {
184        self.request = self.request.query("start_date_min", date.into());
185        self
186    }
187
188    /// Set latest start date (ISO 8601 format)
189    pub fn start_date_max(mut self, date: impl Into<String>) -> Self {
190        self.request = self.request.query("start_date_max", date.into());
191        self
192    }
193
194    /// Set earliest end date (ISO 8601 format)
195    pub fn end_date_min(mut self, date: impl Into<String>) -> Self {
196        self.request = self.request.query("end_date_min", date.into());
197        self
198    }
199
200    /// Set latest end date (ISO 8601 format)
201    pub fn end_date_max(mut self, date: impl Into<String>) -> Self {
202        self.request = self.request.query("end_date_max", date.into());
203        self
204    }
205
206    /// Execute the request
207    pub async fn send(self) -> Result<Vec<Event>, GammaError> {
208        self.request.send().await
209    }
210}
211
212#[cfg(test)]
213mod tests {
214    use crate::Gamma;
215
216    fn gamma() -> Gamma {
217        Gamma::new().unwrap()
218    }
219
220    /// Verify that all event builder methods chain correctly
221    #[test]
222    fn test_list_events_full_chain() {
223        let _list = gamma()
224            .events()
225            .list()
226            .limit(10)
227            .offset(20)
228            .order("volume")
229            .ascending(true)
230            .id(vec![1i64, 2])
231            .tag_id(42)
232            .exclude_tag_id(vec![99i64])
233            .slug(vec!["slug-a"])
234            .tag_slug("politics")
235            .related_tags(true)
236            .active(true)
237            .archived(false)
238            .featured(true)
239            .cyom(false)
240            .include_chat(true)
241            .include_template(false)
242            .recurrence("daily")
243            .closed(false)
244            .liquidity_min(1000.0)
245            .liquidity_max(50000.0)
246            .volume_min(100.0)
247            .volume_max(10000.0)
248            .start_date_min("2024-01-01")
249            .start_date_max("2025-01-01")
250            .end_date_min("2024-06-01")
251            .end_date_max("2025-12-31");
252    }
253
254    #[test]
255    fn test_get_event_accepts_str_and_string() {
256        let _req1 = gamma().events().get("evt-123");
257        let _req2 = gamma().events().get(String::from("evt-123"));
258    }
259
260    #[test]
261    fn test_get_by_slug_accepts_str_and_string() {
262        let _req1 = gamma().events().get_by_slug("slug");
263        let _req2 = gamma().events().get_by_slug(String::from("slug"));
264    }
265
266    #[test]
267    fn test_get_related_by_slug_accepts_str_and_string() {
268        let _req1 = gamma().events().get_related_by_slug("slug");
269        let _req2 = gamma().events().get_related_by_slug(String::from("slug"));
270    }
271}