speedrun_api/api/
endpoint.rs1use std::borrow::Cow;
2
3use async_trait::async_trait;
4use http::Method;
5use serde::de::DeserializeOwned;
6
7use super::{
8 error::BodyError,
9 query::{AsyncQuery, Query},
10 query_params::QueryParams,
11 utils::{build_request, deserialize_response},
12 ApiError, AsyncClient, Client,
13};
14
15pub trait Endpoint {
16 fn method(&self) -> Method {
17 Method::GET
18 }
19
20 fn endpoint(&self) -> Cow<'static, str>;
21
22 fn query_parameters(&self) -> Result<QueryParams<'_>, BodyError> {
23 Ok(QueryParams::default())
24 }
25
26 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
27 Ok(None)
28 }
29
30 fn requires_authentication(&self) -> bool {
33 false
34 }
35}
36
37impl<E, T, C> Query<T, C> for E
38where
39 E: Endpoint,
40 T: DeserializeOwned,
41 C: Client,
42{
43 fn query(&self, client: &C) -> Result<T, super::ApiError<C::Error>> {
44 let (req, data) = build_request(self, client)?;
45
46 let url = req.uri_ref().cloned().unwrap_or_default();
47
48 let rsp = client.rest(req, data)?;
49
50 deserialize_response::<_>(rsp)
51 .map(|value| value.data)
52 .map_err(|err| ApiError::from_http_response(err, url))
53 }
54}
55
56#[async_trait]
57impl<E, T, C> AsyncQuery<T, C> for E
58where
59 E: Endpoint + Sync,
60 T: DeserializeOwned + 'static,
61 C: AsyncClient + Sync,
62{
63 async fn query_async(&self, client: &C) -> Result<T, ApiError<C::Error>> {
64 let (req, data) = build_request(self, client)?;
65 let url = req.uri_ref().cloned().unwrap_or_default();
66
67 let rsp = client.rest_async(req, data).await?;
68
69 deserialize_response::<_>(rsp)
70 .map(|value| value.data)
71 .map_err(|err| ApiError::from_http_response(err, url))
72 }
73}