mattermost_api_rust_driver/api/
mod.rs1#![allow(dead_code)]
2
3pub mod users;
4pub mod auth;
5
6use reqwest::Method;
7use serde::Deserialize;
8use thiserror::Error;
9
10pub struct ApiClient {
11 client: reqwest::Client,
12 base_url: String,
13}
14
15#[derive(Debug, Error)]
17pub enum ApiError {
18 #[error("Request failed: {0}")]
19 RequestError(#[from] reqwest::Error),
20
21 #[error("Server returned error: {status_code} - {message}")]
22 ServerError {
23 id: String,
24 message: String,
25 detailed_error: String,
26 request_id: String,
27 status_code: u16,
28 },
29
30 #[error("Unsupported HTTP method")]
31 UnsupportedMethod,
32}
33
34#[derive(Deserialize)]
36pub struct ServerErrorResponse {
37 id: String,
38 message: String,
39 detailed_error: String,
40 request_id: String,
41}
42
43impl ApiClient {
45 pub fn new(base_url: String) -> Result<Self, reqwest::Error> {
46 let client = reqwest::Client::new();
47 println!("{}", base_url);
48 Ok(ApiClient { client, base_url })
49 }
50 pub async fn send_request<T: for<'de> Deserialize<'de>>(
51 &self,
52 method: Method,
53 path: &str,
54 body: Option<impl serde::Serialize>, ) -> Result<T, ApiError> {
56 let url = self.get_api_route(path); println!("{} {}", method.as_str(), url);
58
59 let client = &self.client;
60
61 let request = match method {
63 Method::GET => client.get(&url),
64 Method::POST => {
65 let mut req = client.post(&url);
66 if let Some(b) = body {
67 req = req.json(&b);
68 }
69 req
70 }
71
72 Method::PUT => {
73 let mut req = client.put(&url);
74 if let Some(b) = body {
75 req = req.json(&b);
76 }
77 req
78 }
79
80 Method::DELETE => client.delete(&url),
81
82 _ => return Err(ApiError::UnsupportedMethod),
84 };
85
86 let response = request.send().await?;
88
89 self.handle_response(response).await
90 }
91
92 async fn handle_response<T: for<'de> Deserialize<'de>>(
93 &self,
94 response: reqwest::Response,
95 ) -> Result<T, ApiError> {
96 let status = response.status();
97
98 if status.is_success() {
99 Ok(response.json::<T>().await?)
100 } else {
101 let error_response = response.json::<ServerErrorResponse>().await?;
102 Err(ApiError::ServerError {
103 id: error_response.id,
104 message: error_response.message,
105 detailed_error: error_response.detailed_error,
106 request_id: error_response.request_id,
107 status_code: status.into(),
108 })
109 }
110 }
111
112 pub fn get_route(&self, path: &str) -> String {
113 format!("{}{}", self.base_url, path)
114 }
115
116 pub fn get_api_route(&self, path: &str) -> String {
117 format!("{}/api/v4{}", self.base_url, path)
118 }
119}