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
108        let state = basin_state_for_deleted_at(deleted_at.as_ref());
109
110        Ok(Self {
111            name,
112            location,
113            created_at,
114            deleted_at,
115            state,
116        })
117    }
118}
119
120#[rustfmt::skip]
121#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
122#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
123#[serde(rename_all = "kebab-case")]
124pub enum BasinState {
125    /// Basin is active.
126    Active,
127    /// Basin is being deleted.
128    Deleting,
129}
130
131#[rustfmt::skip]
132#[derive(Debug, Clone, Serialize, Deserialize)]
133#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
134pub struct EnsureBasinRequest {
135    /// Basin configuration.
136    pub config: Option<BasinConfig>,
137    /// Basin location.
138    /// If omitted when creating, uses the default location for the account.
139    /// This cannot be changed.
140    pub location: Option<LocationName>,
141}
142
143#[rustfmt::skip]
144#[derive(Debug, Clone, Serialize, Deserialize)]
145#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
146pub struct CreateBasinRequest {
147    /// Basin name which must be globally unique.
148    /// It can be between 8 and 48 bytes in length, and comprise lowercase letters, numbers and hyphens.
149    /// It cannot begin or end with a hyphen.
150    pub basin: BasinName,
151    /// Basin configuration.
152    pub config: Option<BasinConfig>,
153    /// Basin location.
154    /// If omitted when creating, uses the default location for the account.
155    pub location: Option<LocationName>,
156}