Skip to main content

asimov_luma_module/api/
client.rs

1// This is free and unencumbered software released into the public domain.
2
3use crate::api::Error;
4use crate::api::models::{Pagination, Root};
5use reqwest::{Client as ReqwestClient, ClientBuilder as ReqwestClientBuilder, Url};
6
7pub type Result<T, E = Error> = std::result::Result<T, E>;
8
9pub struct Client {
10    client: ReqwestClient,
11}
12
13impl Client {
14    #[allow(clippy::new_without_default)]
15    pub fn new() -> Self {
16        Self {
17            client: ReqwestClientBuilder::new()
18                .user_agent("asimov-luma-module")
19                .build()
20                .unwrap(),
21        }
22    }
23
24    pub async fn get_featured_calendars(&self) -> Result<Root> {
25        let url = Url::parse("https://api.lu.ma/calendar/get-featured-calendars").unwrap();
26        let response = self.client.get(url).send().await?;
27        response.error_for_status_ref()?;
28        Ok(response.json::<Root>().await?)
29    }
30
31    pub async fn list_categories(&self) -> Result<Pagination> {
32        let url =
33            Url::parse("https://api.lu.ma/discover/category/list-categories?pagination_limit=20")
34                .unwrap();
35        let response = self.client.get(url).send().await?;
36        response.error_for_status_ref()?;
37        Ok(response.json::<Pagination>().await?)
38    }
39
40    pub async fn list_places(&self) -> Result<Root> {
41        let url = Url::parse("https://api.lu.ma/discover/list-places").unwrap();
42        let response = self.client.get(url).send().await?;
43        response.error_for_status_ref()?;
44        Ok(response.json::<Root>().await?)
45    }
46
47    pub async fn get_category_by_id<S>(&self, id: S) -> Result<serde_json::Value>
48    where
49        S: AsRef<str>,
50    {
51        let url = Url::parse(&format!(
52            "https://api.lu.ma/discover/category/get-page?discover_category_api_id={}",
53            id.as_ref()
54        ))
55        .unwrap();
56        let response = self.client.get(url).send().await?;
57        response.error_for_status_ref()?;
58        Ok(response.json().await?)
59    }
60
61    pub async fn get_category_by_slug<S>(&self, slug: S) -> Result<serde_json::Value>
62    where
63        S: AsRef<str>,
64    {
65        let url = Url::parse(&format!(
66            "https://api.lu.ma/discover/category/get-page?slug={}",
67            slug.as_ref()
68        ))
69        .unwrap();
70        let response = self.client.get(url).send().await?;
71        response.error_for_status_ref()?;
72        Ok(response.json().await?)
73    }
74
75    pub async fn get_calendars_for_place<S>(&self, place: S) -> Result<serde_json::Value>
76    where
77        S: AsRef<str>,
78    {
79        let url = Url::parse(&format!(
80            "https://api.lu.ma/discover/get-calendars?discover_place_api_id={}",
81            place.as_ref()
82        ))
83        .unwrap();
84        let response = self.client.get(url).send().await?;
85        response.error_for_status_ref()?;
86        Ok(response.json().await?)
87    }
88
89    pub async fn get_place_by_id<S>(&self, id: S) -> Result<serde_json::Value>
90    where
91        S: AsRef<str>,
92    {
93        let url = Url::parse(&format!(
94            "https://api.lu.ma/discover/get-place-v2?discover_place_api_id={}",
95            id.as_ref()
96        ))
97        .unwrap();
98        let response = self.client.get(url).send().await?;
99        response.error_for_status_ref()?;
100        Ok(response.json().await?)
101    }
102
103    pub async fn get_place_by_slug<S>(&self, slug: S) -> Result<serde_json::Value>
104    where
105        S: AsRef<str>,
106    {
107        let url = Url::parse(&format!(
108            "https://api.lu.ma/discover/get-place-v2?slug={}",
109            slug.as_ref()
110        ))
111        .unwrap();
112        let response = self.client.get(url).send().await?;
113        response.error_for_status_ref()?;
114        Ok(response.json().await?)
115    }
116
117    pub async fn get_place_events<S1, S2>(
118        &self,
119        place_id: S1,
120        cursor: Option<S2>,
121        limit: Option<u32>,
122    ) -> Result<Pagination>
123    where
124        S1: AsRef<str>,
125        S2: AsRef<str>,
126    {
127        let url = Url::parse(&format!(
128            "https://api.lu.ma/discover/get-paginated-events?discover_place_api_id={}{}{}",
129            place_id.as_ref(),
130            if let Some(cursor) = cursor {
131                format!("&pagination_cursor={}", cursor.as_ref())
132            } else {
133                "".to_string()
134            },
135            if let Some(limit) = limit {
136                format!("&pagination_limit={limit}")
137            } else {
138                "".to_string()
139            }
140        ))
141        .unwrap();
142        let response = self.client.get(url).send().await?;
143        response.error_for_status_ref()?;
144        Ok(response.json().await?)
145    }
146
147    pub async fn get_calendar_by_id<S>(&self, id: S) -> Result<serde_json::Value>
148    where
149        S: AsRef<str>,
150    {
151        let url = Url::parse(&format!(
152            "https://api.lu.ma/calendar/get?api_id={}",
153            id.as_ref()
154        ))
155        .unwrap();
156        let response = self.client.get(url).send().await?;
157        Ok(response.json().await?)
158    }
159
160    pub async fn get_calendar_events<S1, S2>(
161        &self,
162        calendar: S1,
163        cursor: Option<S2>,
164        limit: Option<u32>,
165    ) -> Result<serde_json::Value>
166    where
167        S1: AsRef<str>,
168        S2: AsRef<str>,
169    {
170        let url = Url::parse(&format!(
171            "https://api.lu.ma/calendar/get-items?calendar_api_id={}{}{}&period=future",
172            calendar.as_ref(),
173            if let Some(cursor) = cursor {
174                format!("&pagination_cursor={}", cursor.as_ref())
175            } else {
176                "".to_string()
177            },
178            if let Some(limit) = limit {
179                format!("&pagination_limit={limit}")
180            } else {
181                "".to_string()
182            }
183        ))
184        .unwrap();
185        let response = self.client.get(url).send().await?;
186        response.error_for_status_ref()?;
187        Ok(response.json().await?)
188    }
189
190    pub async fn get_event<S>(&self, event: S) -> Result<serde_json::Value>
191    where
192        S: AsRef<str>,
193    {
194        let url = Url::parse(&format!(
195            "https://api.lu.ma/event/get?event_api_id={}",
196            event.as_ref()
197        ))
198        .unwrap();
199        let response = self.client.get(url).send().await?;
200        response.error_for_status_ref()?;
201        Ok(response.json().await?)
202    }
203
204    pub async fn get_nearby_events<S>(&self, category: Option<S>) -> Result<serde_json::Value>
205    where
206        S: AsRef<str>,
207    {
208        let url = Url::parse(&format!(
209            "https://api.lu.ma/discover/get-paginated-events?pagination_limit=50{}",
210            if let Some(category) = category {
211                format!("&slug={}", category.as_ref())
212            } else {
213                "".to_string()
214            }
215        ))
216        .unwrap();
217        let response = self.client.get(url).send().await?;
218        response.error_for_status_ref()?;
219        Ok(response.json().await?)
220    }
221}