1use s2_common::{
2 self,
3 basin::{BasinName, BasinNamePrefix, BasinNameStartAfter},
4 location::LocationName,
5};
6use serde::{Deserialize, Serialize};
7use time::OffsetDateTime;
8
9use super::config::BasinConfig;
10
11#[rustfmt::skip]
12#[derive(Debug, Clone, Serialize, Deserialize)]
13#[cfg_attr(feature = "utoipa", derive(utoipa::IntoParams))]
14#[cfg_attr(feature = "utoipa", into_params(parameter_in = Query))]
15pub struct ListBasinsRequest {
16 #[cfg_attr(feature = "utoipa", param(value_type = String, default = "", required = false))]
18 pub prefix: Option<BasinNamePrefix>,
19 #[cfg_attr(feature = "utoipa", param(value_type = String, default = "", required = false))]
21 pub start_after: Option<BasinNameStartAfter>,
22 #[cfg_attr(feature = "utoipa", param(value_type = usize, maximum = 1000, default = 1000, required = false))]
24 pub limit: Option<usize>,
25}
26
27super::impl_list_request_conversions!(ListBasinsRequest, BasinNamePrefix, BasinNameStartAfter);
28
29#[rustfmt::skip]
30#[derive(Debug, Clone, Serialize, Deserialize)]
31#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
32pub struct ListBasinsResponse {
33 #[cfg_attr(feature = "utoipa", schema(max_items = 1000))]
35 pub basins: Vec<BasinInfo>,
36 pub has_more: bool,
38}
39
40#[rustfmt::skip]
41#[derive(Debug, Clone, Serialize)]
42#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
43pub struct BasinInfo {
44 pub name: BasinName,
46 pub location: Option<LocationName>,
48 #[serde(with = "time::serde::rfc3339")]
50 pub created_at: OffsetDateTime,
51 #[serde(default, with = "time::serde::rfc3339::option")]
53 pub deleted_at: Option<OffsetDateTime>,
54 #[cfg_attr(feature = "utoipa", schema(ignore))]
56 pub state: BasinState,
57}
58
59impl From<s2_common::basin::BasinInfo> for BasinInfo {
60 fn from(value: s2_common::basin::BasinInfo) -> Self {
61 let s2_common::basin::BasinInfo {
62 name,
63 location,
64 created_at,
65 deleted_at,
66 } = value;
67
68 Self {
69 name,
70 location,
71 created_at,
72 deleted_at,
73 state: basin_state_for_deleted_at(deleted_at.as_ref()),
74 }
75 }
76}
77
78fn basin_state_for_deleted_at(deleted_at: Option<&OffsetDateTime>) -> BasinState {
79 if deleted_at.is_some() {
80 BasinState::Deleting
81 } else {
82 BasinState::Active
83 }
84}
85
86#[derive(Deserialize)]
87struct BasinInfoSerde {
88 name: BasinName,
89 location: Option<LocationName>,
90 #[serde(with = "time::serde::rfc3339")]
91 created_at: OffsetDateTime,
92 #[serde(default, with = "time::serde::rfc3339::option")]
93 deleted_at: Option<OffsetDateTime>,
94}
95
96impl<'de> Deserialize<'de> for BasinInfo {
97 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
98 where
99 D: serde::Deserializer<'de>,
100 {
101 let BasinInfoSerde {
102 name,
103 location,
104 created_at,
105 deleted_at,
106 } = BasinInfoSerde::deserialize(deserializer)?;
107 let state = basin_state_for_deleted_at(deleted_at.as_ref());
108
109 Ok(Self {
110 name,
111 location,
112 created_at,
113 deleted_at,
114 state,
115 })
116 }
117}
118
119#[rustfmt::skip]
120#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
121#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
122#[serde(rename_all = "kebab-case")]
123pub enum BasinState {
124 Active,
126 Deleting,
128}
129
130#[rustfmt::skip]
131#[derive(Debug, Clone, Serialize, Deserialize)]
132#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
133pub struct EnsureBasinRequest {
134 pub config: Option<BasinConfig>,
136 pub location: Option<LocationName>,
140}
141
142#[rustfmt::skip]
143#[derive(Debug, Clone, Serialize, Deserialize)]
144#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
145pub struct CreateBasinRequest {
146 pub basin: BasinName,
150 pub config: Option<BasinConfig>,
152 pub location: Option<LocationName>,
155}