mistral_api/
client.rs

1use reqwest::{Client, Request, StatusCode};
2use serde::de::DeserializeOwned;
3use serde_json::Value;
4use thiserror::Error;
5
6pub trait Endpoint {
7    type Response: DeserializeOwned;
8    fn request(&self, client: &Client) -> Request;
9}
10
11#[derive(Debug, Error)]
12pub enum ApiError {
13    #[error("Client error: {0}")]
14    Client(#[from] reqwest::Error),
15    #[error("Mistral internal server error: {0}")]
16    Server(StatusCode, Vec<u8>),
17    #[error("Mistral error: {0}")]
18    Mistral(Value),
19    #[error("JSON parse error: {0}")]
20    Json(#[from] serde_json::Error),
21}
22
23pub type QueryResult<T> = Result<T, ApiError>;
24
25pub trait Query: Endpoint {
26    async fn query(&self, client: &Client) -> QueryResult<Self::Response>;
27}
28
29impl<E> Query for E
30where
31    E: Endpoint,
32{
33    async fn query(&self, client: &Client) -> QueryResult<Self::Response> {
34        let rsp = client.execute(self.request(client)).await?;
35        let status = rsp.status();
36        let raw_body = rsp.bytes().await?;
37        let val = serde_json::from_slice::<Value>(raw_body.as_ref())
38            .map_err(|_| ApiError::Server(status, raw_body.to_vec()))?;
39        if !status.is_success() {
40            return Err(ApiError::Mistral(val));
41        }
42        serde_json::from_value(val).map_err(ApiError::Json)
43    }
44}