Skip to main content

neptunium_http/
endpoints.rs

1use std::string::FromUtf8Error;
2
3use serde::de::DeserializeOwned;
4
5use crate::{
6    error::{ApiErrorResponse, ApiRateLimitedResponse},
7    request::Request,
8};
9
10pub mod channel;
11pub mod gateway;
12pub mod guild;
13pub mod invites;
14pub mod meta;
15#[cfg(feature = "user_api")]
16pub mod saved_media;
17pub mod webhooks;
18
19impl<T: DeserializeOwned> ResponseBody for T {
20    fn deserialize(bytes: Vec<u8>) -> Result<Self, Box<ExecuteEndpointRequestError>> {
21        if bytes.is_empty() {
22            let mut deserializer = serde_json::Deserializer::from_str("null");
23            Ok(serde_path_to_error::deserialize(&mut deserializer)?)
24        } else {
25            let s = String::from_utf8(bytes).map_err(ExecuteEndpointRequestError::NonUtf8Bytes)?;
26            let mut deserializer = serde_json::Deserializer::from_str(&s);
27            Ok(serde_path_to_error::deserialize(&mut deserializer)?)
28        }
29    }
30}
31
32pub trait ResponseBody: Sized {
33    /// Deserialize, given the response body bytes.
34    /// # Errors
35    /// Returns an error if deserializing failed.
36    fn deserialize(bytes: Vec<u8>) -> Result<Self, Box<ExecuteEndpointRequestError>>;
37}
38
39// Trait bounds to make sure all endpoints implement these, they aren't technically required.
40pub trait Endpoint: Clone + std::fmt::Debug {
41    type Response: ResponseBody;
42    fn into_request(self) -> Request;
43    // async fn deserialize_response(
44    //     response: reqwest::Response,
45    // ) -> Result<Self::Response, ExecuteEndpointRequestError> {
46    //     if response.status() == StatusCode::OK || response.status() == StatusCode::NO_CONTENT {
47    //         if size_of::<Self::Response>() == 0 {
48    //             let mut deserializer = serde_json::Deserializer::from_slice(&[]);
49    //             Ok(serde_path_to_error::deserialize(&mut deserializer)?)
50    //         } else {
51    //             let body = String::from_utf8(response.bytes().await?.to_vec())
52    //                 .map_err(ExecuteEndpointRequestError::NonUtf8Bytes)?;
53    //             let mut deserializer = serde_json::Deserializer::from_str(&body);
54    //             Ok(serde_path_to_error::deserialize(&mut deserializer)?)
55    //         }
56    //     } else {
57    //         Err(ExecuteEndpointRequestError::ResponseNotOk(response))
58    //     }
59    // }
60}
61
62#[derive(Debug)]
63pub enum ExecuteEndpointRequestError {
64    NetworkError(reqwest::Error),
65    ResponseNotOk(reqwest::Response),
66    DeserializationError(serde_path_to_error::Error<serde_json::Error>),
67    NonUtf8Bytes(FromUtf8Error),
68    // TODO: Add fields to this and stuff.
69    // Also need to actually implement rate limit handling
70    // and waiting until the rate limit expires so that the
71    // user doesn't need to worry about this.
72    /// 429 Too Many Requests.
73    RateLimited(ApiRateLimitedResponse),
74    /// 400 Bad Request.
75    BadRequest(ApiErrorResponse),
76    /// 401 Unauthorized.
77    Unauthorized(ApiErrorResponse),
78    /// 403 Forbidden.
79    Forbidden(ApiErrorResponse),
80    /// 404 Not Found.
81    NotFound(ApiErrorResponse),
82    /// 500 Internal Server Error.
83    InternalServerError(ApiErrorResponse),
84}
85
86impl From<reqwest::Error> for ExecuteEndpointRequestError {
87    fn from(value: reqwest::Error) -> Self {
88        Self::NetworkError(value)
89    }
90}
91
92impl From<reqwest::Error> for Box<ExecuteEndpointRequestError> {
93    fn from(value: reqwest::Error) -> Self {
94        Box::new(ExecuteEndpointRequestError::NetworkError(value))
95    }
96}
97
98impl From<serde_path_to_error::Error<serde_json::Error>> for Box<ExecuteEndpointRequestError> {
99    fn from(value: serde_path_to_error::Error<serde_json::Error>) -> Self {
100        Box::new(ExecuteEndpointRequestError::DeserializationError(value))
101    }
102}
103
104impl From<serde_path_to_error::Error<serde_json::Error>> for ExecuteEndpointRequestError {
105    fn from(value: serde_path_to_error::Error<serde_json::Error>) -> Self {
106        Self::DeserializationError(value)
107    }
108}