diff --git a/api/src/v1/config.rs b/api/src/v1/config.rs index d48c9a87..5ec7beba 100644 --- a/api/src/v1/config.rs +++ b/api/src/v1/config.rs @@ -9,10 +9,12 @@ use serde::{Deserialize, Serialize}; #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(rename_all = "kebab-case")] pub enum StorageClass { - /// Append tail latency under 400 milliseconds with s2.dev. + /// Append tail latency under 400 ms with s2.dev. Standard, - /// Append tail latency under 40 milliseconds with s2.dev. + /// Append tail latency under 40 ms with s2.dev. Express, + /// Append tail latency under 4 ms with s2.dev. + Native, } impl From for s2_common::config::StorageClass { @@ -20,6 +22,7 @@ impl From for s2_common::config::StorageClass { match value { StorageClass::Express => Self::Express, StorageClass::Standard => Self::Standard, + StorageClass::Native => Self::Native, } } } @@ -29,6 +32,7 @@ impl From for StorageClass { match value { s2_common::config::StorageClass::Express => Self::Express, s2_common::config::StorageClass::Standard => Self::Standard, + s2_common::config::StorageClass::Native => Self::Native, } } } @@ -598,7 +602,11 @@ mod tests { use super::*; fn gen_storage_class() -> impl Strategy { - prop_oneof![Just(StorageClass::Standard), Just(StorageClass::Express)] + prop_oneof![ + Just(StorageClass::Standard), + Just(StorageClass::Express), + Just(StorageClass::Native), + ] } fn gen_timestamping_mode() -> impl Strategy { diff --git a/cli/schema.json b/cli/schema.json index c6f9c997..3659ddcb 100644 --- a/cli/schema.json +++ b/cli/schema.json @@ -139,7 +139,8 @@ "type": "string", "enum": [ "standard", - "express" + "express", + "native" ] }, "RetentionPolicy": { diff --git a/cli/src/apply.rs b/cli/src/apply.rs index 7235508d..0855ccce 100644 --- a/cli/src/apply.rs +++ b/cli/src/apply.rs @@ -49,6 +49,7 @@ fn storage_class_from_sdk(storage_class: s2_sdk::types::StorageClass) -> Storage match storage_class { s2_sdk::types::StorageClass::Standard => StorageClass::Standard, s2_sdk::types::StorageClass::Express => StorageClass::Express, + s2_sdk::types::StorageClass::Native => StorageClass::Native, } } @@ -127,6 +128,7 @@ fn storage_class_to_sdk( match storage_class { s2_resource_spec::StorageClass::Standard => s2_sdk::types::StorageClass::Standard, s2_resource_spec::StorageClass::Express => s2_sdk::types::StorageClass::Express, + s2_resource_spec::StorageClass::Native => s2_sdk::types::StorageClass::Native, } } @@ -311,6 +313,7 @@ fn format_storage_class(sc: StorageClass) -> &'static str { match sc { StorageClass::Standard => "standard", StorageClass::Express => "express", + StorageClass::Native => "native", } } diff --git a/cli/src/types.rs b/cli/src/types.rs index 699a04b9..3acd5534 100644 --- a/cli/src/types.rs +++ b/cli/src/types.rs @@ -208,6 +208,7 @@ pub use sdk::types::LocationName; pub enum StorageClass { Standard, Express, + Native, } #[derive(ValueEnum, Debug, Clone, Serialize)] @@ -322,6 +323,7 @@ impl From for sdk::types::StorageClass { match class { StorageClass::Standard => sdk::types::StorageClass::Standard, StorageClass::Express => sdk::types::StorageClass::Express, + StorageClass::Native => sdk::types::StorageClass::Native, } } } @@ -331,6 +333,7 @@ impl From for StorageClass { match class { sdk::types::StorageClass::Standard => StorageClass::Standard, sdk::types::StorageClass::Express => StorageClass::Express, + sdk::types::StorageClass::Native => StorageClass::Native, } } } diff --git a/common/src/config.rs b/common/src/config.rs index 83526ec2..338a02e4 100644 --- a/common/src/config.rs +++ b/common/src/config.rs @@ -49,6 +49,8 @@ pub enum StorageClass { #[default] #[strum(serialize = "express")] Express = 2, + #[strum(serialize = "native")] + Native = 3, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] diff --git a/resource-spec/src/lib.rs b/resource-spec/src/lib.rs index 7a0ea7fa..99531fe5 100644 --- a/resource-spec/src/lib.rs +++ b/resource-spec/src/lib.rs @@ -70,6 +70,7 @@ pub struct StreamConfig { pub enum StorageClass { Standard, Express, + Native, } impl schemars::JsonSchema for StorageClass { @@ -81,7 +82,7 @@ impl schemars::JsonSchema for StorageClass { schemars::json_schema!({ "type": "string", "description": "Storage class for recent writes.", - "enum": ["standard", "express"] + "enum": ["standard", "express", "native"] }) } } @@ -91,6 +92,7 @@ impl From for s2_common::config::StorageClass { match s { StorageClass::Standard => Self::Standard, StorageClass::Express => Self::Express, + StorageClass::Native => Self::Native, } } } diff --git a/sdk/src/types.rs b/sdk/src/types.rs index a66f8c44..1c0e3af2 100644 --- a/sdk/src/types.rs +++ b/sdk/src/types.rs @@ -734,10 +734,12 @@ impl Page { #[derive(Debug, Clone, Copy, PartialEq, Eq)] /// Storage class for recent appends. pub enum StorageClass { - /// Standard storage class that offers append latencies under `500ms`. + /// Append tail latency under 400 ms with s2.dev. Standard, - /// Express storage class that offers append latencies under `50ms`. + /// Append tail latency under 40 ms with s2.dev. Express, + /// Append tail latency under 4 ms with s2.dev. + Native, } impl From for StorageClass { @@ -745,6 +747,7 @@ impl From for StorageClass { match value { api::config::StorageClass::Standard => StorageClass::Standard, api::config::StorageClass::Express => StorageClass::Express, + api::config::StorageClass::Native => StorageClass::Native, } } } @@ -754,6 +757,7 @@ impl From for api::config::StorageClass { match value { StorageClass::Standard => api::config::StorageClass::Standard, StorageClass::Express => api::config::StorageClass::Express, + StorageClass::Native => api::config::StorageClass::Native, } } } @@ -4115,11 +4119,21 @@ mod tests { // -- StorageClass -- #[rstest] - #[case::standard(StorageClass::Standard)] - #[case::express(StorageClass::Express)] - fn storage_class_roundtrip(#[case] sdk: StorageClass) { + #[case::standard(StorageClass::Standard, "standard", 1)] + #[case::express(StorageClass::Express, "express", 2)] + #[case::native(StorageClass::Native, "native", 3)] + fn storage_class_roundtrip(#[case] sdk: StorageClass, #[case] wire: &str, #[case] repr: u8) { let api: api::config::StorageClass = sdk.into(); - let back: StorageClass = api.into(); + assert_eq!(serde_json::to_value(api).unwrap(), wire); + let decoded: api::config::StorageClass = + serde_json::from_value(serde_json::json!(wire)).unwrap(); + let common: s2_common::config::StorageClass = decoded.into(); + assert_eq!(common as u8, repr); + assert_eq!( + s2_common::config::StorageClass::from_repr(repr), + Some(common) + ); + let back: StorageClass = api::config::StorageClass::from(common).into(); assert_eq!(back, sdk); }