Skip to main content

s2_api/v1/
basin.rs

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    /// Filter to basins whose names begin with this prefix.
17    #[cfg_attr(feature = "utoipa", param(value_type = String, default = "", required = false))]
18    pub prefix: Option<BasinNamePrefix>,
19    /// Filter to basins whose names lexicographically start after this string.
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!(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    /// Matching basins.
34    #[cfg_attr(feature = "utoipa", schema(max_items = 1000))]
35    pub basins: Vec<BasinInfo>,
36    /// Indicates that there are more basins that match the criteria.
37    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    /// Basin name.
45    pub name: BasinName,
46    /// Basin location.
47    pub location: Option<LocationName>,
48    /// Creation time in RFC 3339 format.
49    #[serde(with = "time::serde::rfc3339")]
50    pub created_at: OffsetDateTime,
51    /// Deletion time in RFC 3339 format, if the basin is being deleted.
52    #[serde(default, with = "time::serde::rfc3339::option")]
53    pub deleted_at: Option<OffsetDateTime>,
54    /// Deprecated basin state inferred from `deleted_at`.
55    #[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    /// Basin is active.
125    Active,
126    /// Basin is being deleted.
127    Deleting,
128}
129
130#[rustfmt::skip]
131#[derive(Debug, Clone, Serialize, Deserialize)]
132#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
133pub struct EnsureBasinRequest {
134    /// Basin configuration.
135    pub config: Option<BasinConfig>,
136    /// Basin location.
137    /// If omitted when creating, uses the default location for the account.
138    /// This cannot be changed.
139    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    /// Basin name which must be globally unique.
147    /// It can be between 8 and 48 bytes in length, and comprise lowercase letters, numbers and hyphens.
148    /// It cannot begin or end with a hyphen.
149    pub basin: BasinName,
150    /// Basin configuration.
151    pub config: Option<BasinConfig>,
152    /// Basin location.
153    /// If omitted when creating, uses the default location for the account.
154    pub location: Option<LocationName>,
155}