jax_daemon/http_server/api/client/
client.rs1use reqwest::Client;
2use url::Url;
3use uuid::Uuid;
4
5use super::error::ApiError;
6use super::ApiRequest;
7use crate::http_server::api::v0::bucket::list::{ListRequest, ListResponse};
8
9#[derive(Debug, Clone)]
10pub struct ApiClient {
11 pub remote: Url,
12 client: Client,
13}
14
15impl ApiClient {
16 pub fn new(remote: &Url) -> Result<Self, ApiError> {
17 let client = Client::builder().build()?;
18
19 Ok(Self {
20 remote: remote.clone(),
21 client,
22 })
23 }
24
25 pub async fn call<T: ApiRequest>(&mut self, request: T) -> Result<T::Response, ApiError> {
26 let request_builder = request.build_request(&self.remote, &self.client);
27 let response = request_builder.send().await?;
28
29 if response.status().is_success() {
30 Ok(response.json::<T::Response>().await?)
31 } else {
32 Err(ApiError::HttpStatus(
33 response.status(),
34 response.text().await?,
35 ))
36 }
37 }
38
39 pub async fn resolve_bucket_name(&mut self, name: &str) -> Result<Uuid, ApiError> {
42 let request = ListRequest {
43 prefix: Some(name.to_string()),
44 limit: Some(100),
45 };
46
47 let response: ListResponse = self.call(request).await?;
48
49 response
50 .buckets
51 .into_iter()
52 .find(|b| b.name == name)
53 .map(|b| b.bucket_id)
54 .ok_or_else(|| {
55 ApiError::HttpStatus(
56 reqwest::StatusCode::NOT_FOUND,
57 format!("Bucket not found: {}", name),
58 )
59 })
60 }
61
62 pub fn base_url(&self) -> &Url {
64 &self.remote
65 }
66
67 pub fn http_client(&self) -> &Client {
69 &self.client
70 }
71}
72
73pub async fn resolve_bucket(client: &mut ApiClient, identifier: &str) -> Result<Uuid, ApiError> {
77 if let Ok(uuid) = Uuid::parse_str(identifier) {
78 return Ok(uuid);
79 }
80 client.resolve_bucket_name(identifier).await
81}