1use s2_common::types::{
2 self,
3 basin::{BasinName, BasinNamePrefix, BasinNameStartAfter},
4};
5use serde::{Deserialize, Serialize};
6use time::OffsetDateTime;
7
8use super::config::{BasinConfig, BasinReconfiguration};
9
10#[rustfmt::skip]
11#[derive(Debug, Clone, Serialize, Deserialize)]
12#[cfg_attr(feature = "utoipa", derive(utoipa::IntoParams))]
13#[cfg_attr(feature = "utoipa", into_params(parameter_in = Query))]
14pub struct ListBasinsRequest {
15 #[cfg_attr(feature = "utoipa", param(value_type = String, default = "", required = false))]
17 pub prefix: Option<BasinNamePrefix>,
18 #[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!(
28 ListBasinsRequest,
29 types::basin::BasinNamePrefix,
30 types::basin::BasinNameStartAfter
31);
32
33#[rustfmt::skip]
34#[derive(Debug, Clone, Serialize, Deserialize)]
35#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
36pub struct ListBasinsResponse {
37 #[cfg_attr(feature = "utoipa", schema(max_items = 1000))]
39 pub basins: Vec<BasinInfo>,
40 pub has_more: bool,
42}
43
44#[rustfmt::skip]
45#[derive(Debug, Clone, Serialize)]
46#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
47pub struct BasinInfo {
48 pub name: BasinName,
50 pub scope: Option<BasinScope>,
52 #[serde(with = "time::serde::rfc3339")]
54 pub created_at: OffsetDateTime,
55 #[serde(default, with = "time::serde::rfc3339::option")]
57 pub deleted_at: Option<OffsetDateTime>,
58 #[cfg_attr(feature = "utoipa", schema(ignore))]
60 pub state: BasinState,
61}
62
63impl From<types::basin::BasinInfo> for BasinInfo {
64 fn from(value: types::basin::BasinInfo) -> Self {
65 let types::basin::BasinInfo {
66 name,
67 scope,
68 created_at,
69 deleted_at,
70 } = value;
71
72 Self {
73 name,
74 scope: scope.map(Into::into),
75 created_at,
76 deleted_at,
77 state: basin_state_for_deleted_at(deleted_at.as_ref()),
78 }
79 }
80}
81
82fn basin_state_for_deleted_at(deleted_at: Option<&OffsetDateTime>) -> BasinState {
83 if deleted_at.is_some() {
84 BasinState::Deleting
85 } else {
86 BasinState::Active
87 }
88}
89
90#[derive(Deserialize)]
91struct BasinInfoSerde {
92 name: BasinName,
93 scope: Option<BasinScope>,
94 #[serde(default, with = "time::serde::rfc3339::option")]
95 created_at: Option<OffsetDateTime>,
96 #[serde(default, with = "time::serde::rfc3339::option")]
97 deleted_at: Option<OffsetDateTime>,
98 state: Option<BasinState>,
99}
100
101impl<'de> Deserialize<'de> for BasinInfo {
102 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
103 where
104 D: serde::Deserializer<'de>,
105 {
106 let BasinInfoSerde {
107 name,
108 scope,
109 created_at,
110 deleted_at,
111 state,
112 } = BasinInfoSerde::deserialize(deserializer)?;
113 let created_at = created_at.unwrap_or_else(OffsetDateTime::now_utc);
114 let deleted_at = match (deleted_at, state) {
115 (Some(deleted_at), _) => Some(deleted_at),
116 (None, Some(BasinState::Deleting)) => Some(OffsetDateTime::now_utc()),
117 (None, _) => None,
118 };
119 let state = basin_state_for_deleted_at(deleted_at.as_ref());
120
121 Ok(Self {
122 name,
123 scope,
124 created_at,
125 deleted_at,
126 state,
127 })
128 }
129}
130
131#[rustfmt::skip]
132#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
133#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
134pub enum BasinScope {
135 #[serde(rename = "aws:us-east-1")]
137 AwsUsEast1,
138}
139
140impl From<BasinScope> for types::basin::BasinScope {
141 fn from(value: BasinScope) -> Self {
142 match value {
143 BasinScope::AwsUsEast1 => Self::AwsUsEast1,
144 }
145 }
146}
147
148impl From<types::basin::BasinScope> for BasinScope {
149 fn from(value: types::basin::BasinScope) -> Self {
150 match value {
151 types::basin::BasinScope::AwsUsEast1 => Self::AwsUsEast1,
152 }
153 }
154}
155
156#[rustfmt::skip]
157#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
158#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
159#[serde(rename_all = "kebab-case")]
160pub enum BasinState {
161 Active,
163 Deleting,
165}
166
167#[rustfmt::skip]
168#[derive(Debug, Clone, Serialize, Deserialize)]
169#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
170pub struct CreateOrReconfigureBasinRequest {
171 pub config: Option<BasinReconfiguration>,
173 pub scope: Option<BasinScope>,
176}
177
178#[rustfmt::skip]
179#[derive(Debug, Clone, Serialize, Deserialize)]
180#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
181pub struct CreateBasinRequest {
182 pub basin: BasinName,
186 pub config: Option<BasinConfig>,
188 pub scope: Option<BasinScope>,
190}