mcai_client/
client.rs

1use crate::{
2  error::{Error, Result},
3  request::Login,
4  response::access_token::AccessToken,
5  Action,
6};
7use reqwest::{header::CONTENT_TYPE, Client as ReqwestClient, Response};
8
9#[derive(Clone, Debug)]
10pub struct Client {
11  pub client: ReqwestClient,
12  pub token: Option<String>,
13  pub hostname: String,
14  pub password: String,
15  pub username: String,
16}
17
18impl Client {
19  pub fn new(hostname: String, username: String, password: String) -> Self {
20    let client = ReqwestClient::new();
21    Client {
22      client,
23      token: None,
24      hostname,
25      password,
26      username,
27    }
28  }
29
30  pub fn get_session_url(&self) -> String {
31    self.build_url("/api/sessions")
32  }
33
34  pub fn build_url(&self, endpoint: &str) -> String {
35    format!("{}{}", self.hostname, endpoint)
36  }
37
38  async fn get_authentication_token(&mut self) -> Result<String> {
39    if let Some(token) = &self.token {
40      return Ok(token.clone());
41    }
42    let login_body = Login::new(self.username.as_str(), self.password.as_str()).to_string();
43
44    let url = self.get_session_url();
45
46    let response = self
47      .client
48      .post(url)
49      .header(CONTENT_TYPE, "application/json")
50      .body(login_body)
51      .send()
52      .await?;
53
54    if !response.status().is_success() {
55      return Err(Error::Runtime("Request failed".to_string()));
56    }
57
58    let token_response: AccessToken = response.json().await?;
59    self.token = Some(token_response.access_token.clone());
60    Ok(token_response.access_token)
61  }
62
63  pub async fn request(&mut self, action: Action) -> Result<Response> {
64    let url = self.build_url(&action.get_url());
65
66    let request = self
67      .client
68      .request(action.get_method(), url)
69      .bearer_auth(self.get_authentication_token().await?);
70
71    let request = if let Some(body) = action.get_body() {
72      request
73        .body(body)
74        .header(CONTENT_TYPE, action.get_content_type().unwrap())
75    } else {
76      request
77    };
78    request.send().await.map_err(Error::Reqwest)
79  }
80
81  pub async fn request_and_parse<T>(&mut self, action: Action) -> Result<T>
82  where
83    T: for<'de> serde::Deserialize<'de>,
84  {
85    let response = self.request(action).await?;
86    let result = response.json::<T>().await?;
87    Ok(result)
88  }
89}