Skip to main content

s2_api/v1/
basin.rs

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    /// Filter to basins whose names begin with this prefix.
16    #[cfg_attr(feature = "utoipa", param(value_type = String, default = "", required = false))]
17    pub prefix: Option<BasinNamePrefix>,
18    /// Filter to basins whose names lexicographically start after this string.
19    /// It must be greater than or equal to the `prefix` if specified.
20    #[cfg_attr(feature = "utoipa", param(value_type = String, default = "", required = false))]
21    pub start_after: Option<BasinNameStartAfter>,
22    /// Number of results, up to a maximum of 1000.
23    #[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    /// Matching basins.
38    #[cfg_attr(feature = "utoipa", schema(max_items = 1000))]
39    pub basins: Vec<BasinInfo>,
40    /// Indicates that there are more basins that match the criteria.
41    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    /// Basin name.
49    pub name: BasinName,
50    /// Basin scope.
51    pub scope: Option<BasinScope>,
52    /// Creation time in RFC 3339 format.
53    #[serde(with = "time::serde::rfc3339")]
54    pub created_at: OffsetDateTime,
55    /// Deletion time in RFC 3339 format, if the basin is being deleted.
56    #[serde(default, with = "time::serde::rfc3339::option")]
57    pub deleted_at: Option<OffsetDateTime>,
58    /// Deprecated basin state inferred from `deleted_at`.
59    #[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    /// AWS `us-east-1` region.
136    #[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    /// Basin is active.
162    Active,
163    /// Basin is being deleted.
164    Deleting,
165}
166
167#[rustfmt::skip]
168#[derive(Debug, Clone, Serialize, Deserialize)]
169#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
170pub struct CreateOrReconfigureBasinRequest {
171    /// Basin reconfiguration.
172    pub config: Option<BasinReconfiguration>,
173    /// Basin scope.
174    /// This cannot be reconfigured.
175    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    /// Basin name which must be globally unique.
183    /// It can be between 8 and 48 bytes in length, and comprise lowercase letters, numbers and hyphens.
184    /// It cannot begin or end with a hyphen.
185    pub basin: BasinName,
186    /// Basin configuration.
187    pub config: Option<BasinConfig>,
188    /// Basin scope.
189    pub scope: Option<BasinScope>,
190}