jax_daemon/http_server/api/v0/bucket/
list.rs1use axum::extract::{Json, State};
2use axum::response::{IntoResponse, Response};
3use reqwest::{Client, RequestBuilder, Url};
4use serde::{Deserialize, Serialize};
5use time::OffsetDateTime;
6use uuid::Uuid;
7
8use common::prelude::Link;
9
10use crate::http_server::api::client::ApiRequest;
11use crate::ServiceState;
12
13#[derive(Debug, Clone, Serialize, Deserialize, clap::Args)]
14pub struct ListRequest {
15 #[serde(skip_serializing_if = "Option::is_none")]
17 #[arg(long)]
18 pub prefix: Option<String>,
19
20 #[serde(skip_serializing_if = "Option::is_none")]
22 #[arg(long)]
23 pub limit: Option<u32>,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct ListResponse {
28 pub buckets: Vec<BucketInfo>,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct BucketInfo {
33 pub bucket_id: Uuid,
34 pub name: String,
35 pub link: Link,
36 #[serde(with = "time::serde::rfc3339")]
37 pub created_at: OffsetDateTime,
38}
39
40pub async fn handler(
41 State(state): State<ServiceState>,
42 Json(req): Json<ListRequest>,
43) -> Result<impl IntoResponse, ListError> {
44 let buckets = state
46 .database()
47 .list_buckets(req.prefix, req.limit)
48 .await
49 .map_err(|e| ListError::Database(e.to_string()))?;
50
51 let bucket_infos = buckets
53 .into_iter()
54 .map(|b| BucketInfo {
55 bucket_id: b.id,
56 name: b.name,
57 link: b.link,
58 created_at: b.created_at,
59 })
60 .collect();
61
62 Ok((
63 http::StatusCode::OK,
64 Json(ListResponse {
65 buckets: bucket_infos,
66 }),
67 )
68 .into_response())
69}
70
71#[derive(Debug, thiserror::Error)]
72pub enum ListError {
73 #[error("Database error: {0}")]
74 Database(String),
75}
76
77impl IntoResponse for ListError {
78 fn into_response(self) -> Response {
79 (
80 http::StatusCode::INTERNAL_SERVER_ERROR,
81 "unknown server error",
82 )
83 .into_response()
84 }
85}
86
87impl ApiRequest for ListRequest {
89 type Response = ListResponse;
90
91 fn build_request(self, base_url: &Url, client: &Client) -> RequestBuilder {
92 let full_url = base_url.join("/api/v0/bucket/list").unwrap();
93 client.post(full_url).json(&self)
94 }
95}