response.rs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. //! HTTP response types
  2. use serde::de::DeserializeOwned;
  3. use crate::error::HttpError;
  4. /// HTTP Response type - generic over the body type R and error type E
  5. /// This is the primary return type for all HTTP operations
  6. pub type Response<R, E = HttpError> = Result<R, E>;
  7. /// Raw HTTP response with status code and body access
  8. #[derive(Debug)]
  9. pub struct RawResponse {
  10. status: u16,
  11. inner: reqwest::Response,
  12. }
  13. impl RawResponse {
  14. /// Create a new RawResponse from a reqwest::Response
  15. pub(crate) fn new(response: reqwest::Response) -> Self {
  16. Self {
  17. status: response.status().as_u16(),
  18. inner: response,
  19. }
  20. }
  21. /// Get the HTTP status code
  22. pub fn status(&self) -> u16 {
  23. self.status
  24. }
  25. /// Check if the response status is a success (2xx)
  26. pub fn is_success(&self) -> bool {
  27. (200..300).contains(&self.status)
  28. }
  29. /// Check if the response status is a client error (4xx)
  30. pub fn is_client_error(&self) -> bool {
  31. (400..500).contains(&self.status)
  32. }
  33. /// Check if the response status is a server error (5xx)
  34. pub fn is_server_error(&self) -> bool {
  35. (500..600).contains(&self.status)
  36. }
  37. /// Get the response body as text
  38. pub async fn text(self) -> Response<String> {
  39. self.inner.text().await.map_err(HttpError::from)
  40. }
  41. /// Get the response body as JSON
  42. pub async fn json<T: DeserializeOwned>(self) -> Response<T> {
  43. self.inner.json().await.map_err(HttpError::from)
  44. }
  45. /// Get the response body as bytes
  46. pub async fn bytes(self) -> Response<Vec<u8>> {
  47. self.inner
  48. .bytes()
  49. .await
  50. .map(|b| b.to_vec())
  51. .map_err(HttpError::from)
  52. }
  53. }
  54. #[cfg(test)]
  55. mod tests {
  56. use super::*;
  57. // Note: RawResponse tests require a real reqwest::Response,
  58. // so they are in tests/integration.rs using mockito.
  59. #[test]
  60. fn test_response_type_is_result() {
  61. // Response<R, E> is just a type alias for Result<R, E>
  62. let success: Response<i32> = Ok(42);
  63. assert!(success.is_ok());
  64. assert!(matches!(success, Ok(42)));
  65. let error: Response<i32> = Err(HttpError::Timeout);
  66. assert!(error.is_err());
  67. assert!(matches!(error, Err(HttpError::Timeout)));
  68. }
  69. }