From 4088a08e0fc345f47a5f60ef5d4d736d17b3c08e Mon Sep 17 00:00:00 2001 From: numinex Date: Mon, 6 Nov 2023 19:16:59 +0100 Subject: [PATCH 1/6] Add CompressionConfig and CompressionAlgorithm enum --- server/src/configs/system.rs | 8 ++ server/src/streaming/compression/algorithm.rs | 108 ++++++++++++++++++ server/src/streaming/compression/mod.rs | 1 + server/src/streaming/mod.rs | 2 + 4 files changed, 119 insertions(+) create mode 100644 server/src/streaming/compression/algorithm.rs create mode 100644 server/src/streaming/compression/mod.rs diff --git a/server/src/configs/system.rs b/server/src/configs/system.rs index 06b41e048..301a34233 100644 --- a/server/src/configs/system.rs +++ b/server/src/configs/system.rs @@ -1,5 +1,6 @@ use crate::configs::resource_quota::MemoryResourceQuota; use serde::{Deserialize, Serialize}; +use crate::streaming::compression::algorithm::CompressionAlgorithm; #[derive(Debug, Deserialize, Serialize)] pub struct SystemConfig { @@ -12,6 +13,7 @@ pub struct SystemConfig { pub partition: PartitionConfig, pub segment: SegmentConfig, pub encryption: EncryptionConfig, + pub compression: CompressionConfig, } #[derive(Debug, Deserialize, Serialize)] @@ -19,6 +21,12 @@ pub struct DatabaseConfig { pub path: String, } +#[derive(Debug, Deserialize, Serialize, Default)] +pub struct CompressionConfig { + pub enabled: bool, + pub alg: CompressionAlgorithm, +} + #[derive(Debug, Deserialize, Serialize)] pub struct LoggingConfig { pub path: String, diff --git a/server/src/streaming/compression/algorithm.rs b/server/src/streaming/compression/algorithm.rs new file mode 100644 index 000000000..864e5aefc --- /dev/null +++ b/server/src/streaming/compression/algorithm.rs @@ -0,0 +1,108 @@ +use std::str::FromStr; +use serde::{Serialize, Serializer, de::{Visitor, self, Deserializer}, Deserialize}; + +// for now only those, in the future will add snappy, lz4, zstd (same as in kafka) in addition to that +// we should consider brotli aswell. +#[derive(Debug, PartialEq, Clone)] +pub enum CompressionAlgorithm { + Producer, + Gzip, +} + +impl Default for CompressionAlgorithm { + fn default() -> Self { + CompressionAlgorithm::Producer + } +} + +impl FromStr for CompressionAlgorithm { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "Producer" | "producer" => Ok(CompressionAlgorithm::Producer), + "Gzip" | "gzip" => Ok(CompressionAlgorithm::Gzip), + _ => Err(format!("Unknown compression type: {}", s)) + } + } +} + +impl Serialize for CompressionAlgorithm { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + CompressionAlgorithm::Producer => serializer.serialize_str("producer"), + CompressionAlgorithm::Gzip => serializer.serialize_str("gzip"), + } + } +} +struct CompressionAlgVisitor; + +impl<'de> Visitor<'de> for CompressionAlgVisitor { + type Value = CompressionAlgorithm; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a valid compression type, check documentation for more information.") + } + + fn visit_str(self, value: &str) -> Result + where + E: de::Error, + { + CompressionAlgorithm::from_str(&value).map_err(de::Error::custom) + } +} + +impl<'de> Deserialize<'de> for CompressionAlgorithm { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(CompressionAlgVisitor) + } +} + + +#[cfg(test)] +mod tests { + use super::*; + use serde_json::json; + + #[test] + fn test_serialize() { + let producer_alg = CompressionAlgorithm::Producer; + let producer_serialized = serde_json::to_string(&producer_alg).unwrap(); + + //gzip alg + let gzip_alg = CompressionAlgorithm::Gzip; + let gzip_serialized = serde_json::to_string(&gzip_alg).unwrap(); + assert_eq!(producer_serialized, json!("producer").to_string()); + assert_eq!(gzip_serialized, json!("gzip").to_string()); + } + + #[test] + fn test_deserialize() { + let json_data = "\"producer\""; + let deserialized: Result = + serde_json::from_str(json_data); + assert!(deserialized.is_ok()); + + let json_data = "\"Producer\""; + let deserialized: Result = + serde_json::from_str(json_data); + assert!(deserialized.is_ok()); + assert_eq!(deserialized.unwrap(), CompressionAlgorithm::Producer); + + let json_data = "\"Gzip\""; + let deserialized: Result = + serde_json::from_str(json_data); + assert!(deserialized.is_ok()); + + let json_data = "\"gzip\""; + let deserialized: Result = + serde_json::from_str(json_data); + assert!(deserialized.is_ok()); + assert_eq!(deserialized.unwrap(), CompressionAlgorithm::Gzip); + } \ No newline at end of file diff --git a/server/src/streaming/compression/mod.rs b/server/src/streaming/compression/mod.rs new file mode 100644 index 000000000..403196fe3 --- /dev/null +++ b/server/src/streaming/compression/mod.rs @@ -0,0 +1 @@ +pub mod algorithm; \ No newline at end of file diff --git a/server/src/streaming/mod.rs b/server/src/streaming/mod.rs index b14027838..164e96cc7 100644 --- a/server/src/streaming/mod.rs +++ b/server/src/streaming/mod.rs @@ -14,3 +14,5 @@ pub mod systems; pub mod topics; pub mod users; pub mod utils; + +pub mod compression; From bea442c791aff0885e83d7cc852d554cf207c045 Mon Sep 17 00:00:00 2001 From: numinex Date: Mon, 6 Nov 2023 20:08:26 +0100 Subject: [PATCH 2/6] Extend server configuration with compression config --- configs/server.json | 4 ++ configs/server.toml | 4 ++ .../compression_algorithm.rs} | 42 +++++++++---------- server/src/configs/defaults.rs | 13 +++++- server/src/configs/displays.rs | 20 +++++++++ server/src/configs/mod.rs | 1 + server/src/configs/system.rs | 6 +-- server/src/streaming/compression/mod.rs | 1 - server/src/streaming/mod.rs | 2 - 9 files changed, 62 insertions(+), 31 deletions(-) rename server/src/{streaming/compression/algorithm.rs => configs/compression_algorithm.rs} (81%) delete mode 100644 server/src/streaming/compression/mod.rs diff --git a/configs/server.json b/configs/server.json index a7fafb620..dead4fd55 100644 --- a/configs/server.json +++ b/configs/server.json @@ -108,6 +108,10 @@ "enabled": false, "key": "" }, + "compression": { + "enabled": true, + "algorithm": "producer" + }, "stream": { "path": "streams" }, diff --git a/configs/server.toml b/configs/server.toml index 4bc7e666a..4fdf26489 100644 --- a/configs/server.toml +++ b/configs/server.toml @@ -95,6 +95,10 @@ size = "4GB" enabled = false key = "" +[system.compression] +enabled = true +algorithm = "producer" + [system.stream] path = "streams" diff --git a/server/src/streaming/compression/algorithm.rs b/server/src/configs/compression_algorithm.rs similarity index 81% rename from server/src/streaming/compression/algorithm.rs rename to server/src/configs/compression_algorithm.rs index 864e5aefc..fffb2b836 100644 --- a/server/src/streaming/compression/algorithm.rs +++ b/server/src/configs/compression_algorithm.rs @@ -1,20 +1,17 @@ +use serde::{ + de::{self, Deserializer, Visitor}, + Deserialize, Serialize, Serializer, +}; use std::str::FromStr; -use serde::{Serialize, Serializer, de::{Visitor, self, Deserializer}, Deserialize}; -// for now only those, in the future will add snappy, lz4, zstd (same as in kafka) in addition to that -// we should consider brotli aswell. +// for now only those, in the future will add snappy, lz4, zstd (same as in confluent kafka) in addition to that +// we should consider brotli as well. #[derive(Debug, PartialEq, Clone)] pub enum CompressionAlgorithm { Producer, Gzip, } -impl Default for CompressionAlgorithm { - fn default() -> Self { - CompressionAlgorithm::Producer - } -} - impl FromStr for CompressionAlgorithm { type Err = String; @@ -22,15 +19,15 @@ impl FromStr for CompressionAlgorithm { match s { "Producer" | "producer" => Ok(CompressionAlgorithm::Producer), "Gzip" | "gzip" => Ok(CompressionAlgorithm::Gzip), - _ => Err(format!("Unknown compression type: {}", s)) + _ => Err(format!("Unknown compression type: {}", s)), } } } impl Serialize for CompressionAlgorithm { fn serialize(&self, serializer: S) -> Result - where - S: Serializer, + where + S: Serializer, { match self { CompressionAlgorithm::Producer => serializer.serialize_str("producer"), @@ -38,9 +35,9 @@ impl Serialize for CompressionAlgorithm { } } } -struct CompressionAlgVisitor; +struct CompressionAlgorithmVisitor; -impl<'de> Visitor<'de> for CompressionAlgVisitor { +impl<'de> Visitor<'de> for CompressionAlgorithmVisitor { type Value = CompressionAlgorithm; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { @@ -48,23 +45,22 @@ impl<'de> Visitor<'de> for CompressionAlgVisitor { } fn visit_str(self, value: &str) -> Result - where - E: de::Error, + where + E: de::Error, { - CompressionAlgorithm::from_str(&value).map_err(de::Error::custom) + CompressionAlgorithm::from_str(value).map_err(de::Error::custom) } } impl<'de> Deserialize<'de> for CompressionAlgorithm { fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, + where + D: Deserializer<'de>, { - deserializer.deserialize_str(CompressionAlgVisitor) + deserializer.deserialize_str(CompressionAlgorithmVisitor) } } - #[cfg(test)] mod tests { use super::*; @@ -75,7 +71,6 @@ mod tests { let producer_alg = CompressionAlgorithm::Producer; let producer_serialized = serde_json::to_string(&producer_alg).unwrap(); - //gzip alg let gzip_alg = CompressionAlgorithm::Gzip; let gzip_serialized = serde_json::to_string(&gzip_alg).unwrap(); assert_eq!(producer_serialized, json!("producer").to_string()); @@ -105,4 +100,5 @@ mod tests { serde_json::from_str(json_data); assert!(deserialized.is_ok()); assert_eq!(deserialized.unwrap(), CompressionAlgorithm::Gzip); - } \ No newline at end of file + } +} diff --git a/server/src/configs/defaults.rs b/server/src/configs/defaults.rs index 83d0a69fe..23dc62ff8 100644 --- a/server/src/configs/defaults.rs +++ b/server/src/configs/defaults.rs @@ -7,8 +7,8 @@ use crate::configs::server::{ PersonalAccessTokenConfig, ServerConfig, }; use crate::configs::system::{ - CacheConfig, DatabaseConfig, EncryptionConfig, LoggingConfig, PartitionConfig, SegmentConfig, - StreamConfig, SystemConfig, TopicConfig, + CacheConfig, CompressionConfig, DatabaseConfig, EncryptionConfig, LoggingConfig, + PartitionConfig, SegmentConfig, StreamConfig, SystemConfig, TopicConfig, }; use crate::configs::tcp::{TcpConfig, TcpTlsConfig}; use std::sync::Arc; @@ -126,6 +126,7 @@ impl Default for SystemConfig { topic: TopicConfig::default(), partition: PartitionConfig::default(), segment: SegmentConfig::default(), + compression: CompressionConfig::default(), } } } @@ -137,6 +138,14 @@ impl Default for DatabaseConfig { } } } +impl Default for CompressionConfig { + fn default() -> Self { + CompressionConfig { + enabled: true, + algorithm: "producer".parse().unwrap(), + } + } +} impl Default for LoggingConfig { fn default() -> LoggingConfig { diff --git a/server/src/configs/displays.rs b/server/src/configs/displays.rs index a4283fe3f..61abdc601 100644 --- a/server/src/configs/displays.rs +++ b/server/src/configs/displays.rs @@ -1,4 +1,6 @@ +use crate::configs::compression_algorithm::CompressionAlgorithm; use crate::configs::quic::{QuicCertificateConfig, QuicConfig}; +use crate::configs::system::CompressionConfig; use crate::configs::{ http::{HttpConfig, HttpCorsConfig, HttpJwtConfig, HttpMetricsConfig, HttpTlsConfig}, resource_quota::MemoryResourceQuota, @@ -98,6 +100,24 @@ impl Display for MemoryResourceQuota { } } } +impl Display for CompressionAlgorithm { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + CompressionAlgorithm::Gzip => write!(f, "gzip"), + CompressionAlgorithm::Producer => write!(f, "producer"), + } + } +} + +impl Display for CompressionConfig { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{{ enabled: {}, algorithm: {} }}", + self.enabled, self.algorithm + ) + } +} impl Display for ServerConfig { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/server/src/configs/mod.rs b/server/src/configs/mod.rs index 28af54fd2..ef5203b24 100644 --- a/server/src/configs/mod.rs +++ b/server/src/configs/mod.rs @@ -5,6 +5,7 @@ pub mod http; pub mod quic; pub mod tcp; +pub mod compression_algorithm; pub mod config_provider; pub mod defaults; pub mod displays; diff --git a/server/src/configs/system.rs b/server/src/configs/system.rs index 301a34233..c4d623646 100644 --- a/server/src/configs/system.rs +++ b/server/src/configs/system.rs @@ -1,6 +1,6 @@ +use crate::configs::compression_algorithm::CompressionAlgorithm; use crate::configs::resource_quota::MemoryResourceQuota; use serde::{Deserialize, Serialize}; -use crate::streaming::compression::algorithm::CompressionAlgorithm; #[derive(Debug, Deserialize, Serialize)] pub struct SystemConfig { @@ -21,10 +21,10 @@ pub struct DatabaseConfig { pub path: String, } -#[derive(Debug, Deserialize, Serialize, Default)] +#[derive(Debug, Deserialize, Serialize)] pub struct CompressionConfig { pub enabled: bool, - pub alg: CompressionAlgorithm, + pub algorithm: CompressionAlgorithm, } #[derive(Debug, Deserialize, Serialize)] diff --git a/server/src/streaming/compression/mod.rs b/server/src/streaming/compression/mod.rs deleted file mode 100644 index 403196fe3..000000000 --- a/server/src/streaming/compression/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod algorithm; \ No newline at end of file diff --git a/server/src/streaming/mod.rs b/server/src/streaming/mod.rs index 164e96cc7..b14027838 100644 --- a/server/src/streaming/mod.rs +++ b/server/src/streaming/mod.rs @@ -14,5 +14,3 @@ pub mod systems; pub mod topics; pub mod users; pub mod utils; - -pub mod compression; From 05babe19844fceffb67dc3e36172f1365336969e Mon Sep 17 00:00:00 2001 From: numinex Date: Mon, 6 Nov 2023 21:29:55 +0100 Subject: [PATCH 3/6] Change test to use Into/From trait instead of serde serialization and remove Producer from compressiong algorithm type --- configs/server.json | 4 +- configs/server.toml | 4 +- server/src/configs/compression_algorithm.rs | 50 ++++++++------------- server/src/configs/defaults.rs | 4 +- server/src/configs/displays.rs | 1 - 5 files changed, 24 insertions(+), 39 deletions(-) diff --git a/configs/server.json b/configs/server.json index dead4fd55..c7c2095dc 100644 --- a/configs/server.json +++ b/configs/server.json @@ -109,8 +109,8 @@ "key": "" }, "compression": { - "enabled": true, - "algorithm": "producer" + "enabled": false, + "algorithm": "gzip" }, "stream": { "path": "streams" diff --git a/configs/server.toml b/configs/server.toml index 4fdf26489..7b8c982fd 100644 --- a/configs/server.toml +++ b/configs/server.toml @@ -96,8 +96,8 @@ enabled = false key = "" [system.compression] -enabled = true -algorithm = "producer" +enabled = false +algorithm = "gzip" [system.stream] path = "streams" diff --git a/server/src/configs/compression_algorithm.rs b/server/src/configs/compression_algorithm.rs index fffb2b836..bef88e0a5 100644 --- a/server/src/configs/compression_algorithm.rs +++ b/server/src/configs/compression_algorithm.rs @@ -8,7 +8,6 @@ use std::str::FromStr; // we should consider brotli as well. #[derive(Debug, PartialEq, Clone)] pub enum CompressionAlgorithm { - Producer, Gzip, } @@ -17,7 +16,6 @@ impl FromStr for CompressionAlgorithm { fn from_str(s: &str) -> Result { match s { - "Producer" | "producer" => Ok(CompressionAlgorithm::Producer), "Gzip" | "gzip" => Ok(CompressionAlgorithm::Gzip), _ => Err(format!("Unknown compression type: {}", s)), } @@ -30,11 +28,17 @@ impl Serialize for CompressionAlgorithm { S: Serializer, { match self { - CompressionAlgorithm::Producer => serializer.serialize_str("producer"), CompressionAlgorithm::Gzip => serializer.serialize_str("gzip"), } } } +impl From for String { + fn from(value: CompressionAlgorithm) -> Self { + match value { + CompressionAlgorithm::Gzip => "gzip".to_string(), + } + } +} struct CompressionAlgorithmVisitor; impl<'de> Visitor<'de> for CompressionAlgorithmVisitor { @@ -64,41 +68,23 @@ impl<'de> Deserialize<'de> for CompressionAlgorithm { #[cfg(test)] mod tests { use super::*; - use serde_json::json; #[test] - fn test_serialize() { - let producer_alg = CompressionAlgorithm::Producer; - let producer_serialized = serde_json::to_string(&producer_alg).unwrap(); + fn test_from() { + let gzip_alg = CompressionAlgorithm::from_str("gzip"); + assert!(gzip_alg.is_ok()); + assert_eq!(gzip_alg.unwrap(), CompressionAlgorithm::Gzip); - let gzip_alg = CompressionAlgorithm::Gzip; - let gzip_serialized = serde_json::to_string(&gzip_alg).unwrap(); - assert_eq!(producer_serialized, json!("producer").to_string()); - assert_eq!(gzip_serialized, json!("gzip").to_string()); + let gzip_alg = CompressionAlgorithm::from_str("Gzip"); + assert!(gzip_alg.is_ok()); + assert_eq!(gzip_alg.unwrap(), CompressionAlgorithm::Gzip); } #[test] - fn test_deserialize() { - let json_data = "\"producer\""; - let deserialized: Result = - serde_json::from_str(json_data); - assert!(deserialized.is_ok()); - - let json_data = "\"Producer\""; - let deserialized: Result = - serde_json::from_str(json_data); - assert!(deserialized.is_ok()); - assert_eq!(deserialized.unwrap(), CompressionAlgorithm::Producer); - - let json_data = "\"Gzip\""; - let deserialized: Result = - serde_json::from_str(json_data); - assert!(deserialized.is_ok()); + fn test_into() { + let gzip: CompressionAlgorithm = CompressionAlgorithm::Gzip; + let gzip_string: String = gzip.into(); - let json_data = "\"gzip\""; - let deserialized: Result = - serde_json::from_str(json_data); - assert!(deserialized.is_ok()); - assert_eq!(deserialized.unwrap(), CompressionAlgorithm::Gzip); + assert_eq!(gzip_string, "gzip".to_string()); } } diff --git a/server/src/configs/defaults.rs b/server/src/configs/defaults.rs index 23dc62ff8..b435cc910 100644 --- a/server/src/configs/defaults.rs +++ b/server/src/configs/defaults.rs @@ -141,8 +141,8 @@ impl Default for DatabaseConfig { impl Default for CompressionConfig { fn default() -> Self { CompressionConfig { - enabled: true, - algorithm: "producer".parse().unwrap(), + enabled: false, + algorithm: "gzip".parse().unwrap(), } } } diff --git a/server/src/configs/displays.rs b/server/src/configs/displays.rs index 61abdc601..c65ce3508 100644 --- a/server/src/configs/displays.rs +++ b/server/src/configs/displays.rs @@ -104,7 +104,6 @@ impl Display for CompressionAlgorithm { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { CompressionAlgorithm::Gzip => write!(f, "gzip"), - CompressionAlgorithm::Producer => write!(f, "producer"), } } } From 75368ea0e1c28488c50eddaa7c4028bd8aa7b485 Mon Sep 17 00:00:00 2001 From: numinnex Date: Tue, 7 Nov 2023 07:35:23 +0100 Subject: [PATCH 4/6] Move compression algorithm enum to sdk crate and enhance it with as/from code methods --- configs/server.json | 27 +--- configs/server.toml | 4 +- iggy/src/compression.rs | 159 ++++++++++++++++++++ iggy/src/lib.rs | 1 + server/src/configs/compression_algorithm.rs | 90 ----------- server/src/configs/defaults.rs | 5 +- server/src/configs/displays.rs | 8 - server/src/configs/mod.rs | 1 - server/src/configs/system.rs | 4 +- 9 files changed, 174 insertions(+), 125 deletions(-) create mode 100644 iggy/src/compression.rs delete mode 100644 server/src/configs/compression_algorithm.rs diff --git a/configs/server.json b/configs/server.json index c7c2095dc..b05a694bd 100644 --- a/configs/server.json +++ b/configs/server.json @@ -4,18 +4,9 @@ "address": "0.0.0.0:3000", "cors": { "enabled": true, - "allowed_methods": [ - "GET", - "POST", - "PUT", - "DELETE" - ], - "allowed_origins": [ - "*" - ], - "allowed_headers": [ - "content-type" - ], + "allowed_methods": ["GET", "POST", "PUT", "DELETE"], + "allowed_origins": ["*"], + "allowed_headers": ["content-type"], "exposed_headers": [], "allow_credentials": false, "allow_private_network": false @@ -24,12 +15,8 @@ "algorithm": "HS256", "issuer": "iggy.rs", "audience": "iggy.rs", - "valid_issuers": [ - "iggy.rs" - ], - "valid_audiences": [ - "iggy.rs" - ], + "valid_issuers": ["iggy.rs"], + "valid_audiences": ["iggy.rs"], "access_token_expiry": 3600, "refresh_token_expiry": 86400, "clock_skew": 5, @@ -109,8 +96,8 @@ "key": "" }, "compression": { - "enabled": false, - "algorithm": "gzip" + "enabled": true, + "algorithm": "none" }, "stream": { "path": "streams" diff --git a/configs/server.toml b/configs/server.toml index 7b8c982fd..338cd8d72 100644 --- a/configs/server.toml +++ b/configs/server.toml @@ -96,8 +96,8 @@ enabled = false key = "" [system.compression] -enabled = false -algorithm = "gzip" +enabled = true +algorithm = "none" [system.stream] path = "streams" diff --git a/iggy/src/compression.rs b/iggy/src/compression.rs new file mode 100644 index 000000000..d9f109933 --- /dev/null +++ b/iggy/src/compression.rs @@ -0,0 +1,159 @@ +use serde::{ + de::{self, Deserializer, Visitor}, + Deserialize, Serialize, Serializer, +}; +use std::{ + fmt::{Display, Formatter}, + str::FromStr, +}; + +use crate::error::Error; + +// for now only those, in the future will add snappy, lz4, zstd (same as in confluent kafka) in addition to that +// we should consider brotli as well. +#[derive(Debug, PartialEq, Clone)] +pub enum CompressionKind { + None, + Gzip, +} + +impl FromStr for CompressionKind { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "Gzip" | "gzip" => Ok(CompressionKind::Gzip), + "None" | "none" => Ok(CompressionKind::None), + _ => Err(format!("Unknown compression type: {}", s)), + } + } +} + +impl CompressionKind { + pub fn as_code(&self) -> u8 { + match self { + CompressionKind::None => 1, + CompressionKind::Gzip => 2, + } + } + + pub fn from_code(code: u8) -> Result { + match code { + 1 => Ok(CompressionKind::None), + 2 => Ok(CompressionKind::Gzip), + _ => Err(Error::InvalidCommand), + } + } +} + +impl Display for CompressionKind { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + CompressionKind::None => write!(f, "none"), + CompressionKind::Gzip => write!(f, "gzip"), + } + } +} + +impl Serialize for CompressionKind { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + CompressionKind::None => serializer.serialize_str("none"), + CompressionKind::Gzip => serializer.serialize_str("gzip"), + } + } +} + +impl From for String { + fn from(value: CompressionKind) -> Self { + match value { + CompressionKind::None => "none".to_string(), + CompressionKind::Gzip => "gzip".to_string(), + } + } +} +struct CompressionKindVisitor; + +impl<'de> Visitor<'de> for CompressionKindVisitor { + type Value = CompressionKind; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a valid compression type, check documentation for more information.") + } + + fn visit_str(self, value: &str) -> Result + where + E: de::Error, + { + CompressionKind::from_str(value).map_err(de::Error::custom) + } +} + +impl<'de> Deserialize<'de> for CompressionKind { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(CompressionKindVisitor) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_from() { + let none_alg = CompressionKind::from_str("none"); + assert!(none_alg.is_ok()); + assert_eq!(none_alg.unwrap(), CompressionKind::None); + + let none_alg = CompressionKind::from_str("None"); + assert!(none_alg.is_ok()); + assert_eq!(none_alg.unwrap(), CompressionKind::None); + + let gzip_alg = CompressionKind::from_str("gzip"); + assert!(gzip_alg.is_ok()); + assert_eq!(gzip_alg.unwrap(), CompressionKind::Gzip); + + let gzip_alg = CompressionKind::from_str("Gzip"); + assert!(gzip_alg.is_ok()); + assert_eq!(gzip_alg.unwrap(), CompressionKind::Gzip); + } + + #[test] + fn test_into() { + let none: CompressionKind = CompressionKind::None; + let none_string: String = none.into(); + + assert_eq!(none_string, "none".to_string()); + + let gzip: CompressionKind = CompressionKind::Gzip; + let gzip_string: String = gzip.into(); + + assert_eq!(gzip_string, "gzip".to_string()); + } + #[test] + fn test_as_code() { + let none = CompressionKind::None; + let none_code = none.as_code(); + assert_eq!(none_code, 1); + + let gzip = CompressionKind::Gzip; + let gzip_code = gzip.as_code(); + assert_eq!(gzip_code, 2); + } + #[test] + fn test_from_code() { + let none = CompressionKind::from_code(1); + assert!(none.is_ok()); + assert_eq!(none.unwrap(), CompressionKind::None); + + let gzip = CompressionKind::from_code(2); + assert!(gzip.is_ok()); + assert_eq!(gzip.unwrap(), CompressionKind::Gzip); + } +} diff --git a/iggy/src/lib.rs b/iggy/src/lib.rs index 02e4cb186..967405f45 100644 --- a/iggy/src/lib.rs +++ b/iggy/src/lib.rs @@ -9,6 +9,7 @@ pub mod clients; #[cfg(feature = "iggy-cmd")] pub mod cmd; pub mod command; +pub mod compression; pub mod consumer; pub mod consumer_groups; pub mod consumer_offsets; diff --git a/server/src/configs/compression_algorithm.rs b/server/src/configs/compression_algorithm.rs deleted file mode 100644 index bef88e0a5..000000000 --- a/server/src/configs/compression_algorithm.rs +++ /dev/null @@ -1,90 +0,0 @@ -use serde::{ - de::{self, Deserializer, Visitor}, - Deserialize, Serialize, Serializer, -}; -use std::str::FromStr; - -// for now only those, in the future will add snappy, lz4, zstd (same as in confluent kafka) in addition to that -// we should consider brotli as well. -#[derive(Debug, PartialEq, Clone)] -pub enum CompressionAlgorithm { - Gzip, -} - -impl FromStr for CompressionAlgorithm { - type Err = String; - - fn from_str(s: &str) -> Result { - match s { - "Gzip" | "gzip" => Ok(CompressionAlgorithm::Gzip), - _ => Err(format!("Unknown compression type: {}", s)), - } - } -} - -impl Serialize for CompressionAlgorithm { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - match self { - CompressionAlgorithm::Gzip => serializer.serialize_str("gzip"), - } - } -} -impl From for String { - fn from(value: CompressionAlgorithm) -> Self { - match value { - CompressionAlgorithm::Gzip => "gzip".to_string(), - } - } -} -struct CompressionAlgorithmVisitor; - -impl<'de> Visitor<'de> for CompressionAlgorithmVisitor { - type Value = CompressionAlgorithm; - - fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { - formatter.write_str("a valid compression type, check documentation for more information.") - } - - fn visit_str(self, value: &str) -> Result - where - E: de::Error, - { - CompressionAlgorithm::from_str(value).map_err(de::Error::custom) - } -} - -impl<'de> Deserialize<'de> for CompressionAlgorithm { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_str(CompressionAlgorithmVisitor) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_from() { - let gzip_alg = CompressionAlgorithm::from_str("gzip"); - assert!(gzip_alg.is_ok()); - assert_eq!(gzip_alg.unwrap(), CompressionAlgorithm::Gzip); - - let gzip_alg = CompressionAlgorithm::from_str("Gzip"); - assert!(gzip_alg.is_ok()); - assert_eq!(gzip_alg.unwrap(), CompressionAlgorithm::Gzip); - } - - #[test] - fn test_into() { - let gzip: CompressionAlgorithm = CompressionAlgorithm::Gzip; - let gzip_string: String = gzip.into(); - - assert_eq!(gzip_string, "gzip".to_string()); - } -} diff --git a/server/src/configs/defaults.rs b/server/src/configs/defaults.rs index b435cc910..4964537db 100644 --- a/server/src/configs/defaults.rs +++ b/server/src/configs/defaults.rs @@ -138,11 +138,12 @@ impl Default for DatabaseConfig { } } } + impl Default for CompressionConfig { fn default() -> Self { CompressionConfig { - enabled: false, - algorithm: "gzip".parse().unwrap(), + enabled: true, + algorithm: "none".parse().unwrap(), } } } diff --git a/server/src/configs/displays.rs b/server/src/configs/displays.rs index c65ce3508..e6a1d3880 100644 --- a/server/src/configs/displays.rs +++ b/server/src/configs/displays.rs @@ -1,4 +1,3 @@ -use crate::configs::compression_algorithm::CompressionAlgorithm; use crate::configs::quic::{QuicCertificateConfig, QuicConfig}; use crate::configs::system::CompressionConfig; use crate::configs::{ @@ -100,13 +99,6 @@ impl Display for MemoryResourceQuota { } } } -impl Display for CompressionAlgorithm { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - CompressionAlgorithm::Gzip => write!(f, "gzip"), - } - } -} impl Display for CompressionConfig { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { diff --git a/server/src/configs/mod.rs b/server/src/configs/mod.rs index ef5203b24..28af54fd2 100644 --- a/server/src/configs/mod.rs +++ b/server/src/configs/mod.rs @@ -5,7 +5,6 @@ pub mod http; pub mod quic; pub mod tcp; -pub mod compression_algorithm; pub mod config_provider; pub mod defaults; pub mod displays; diff --git a/server/src/configs/system.rs b/server/src/configs/system.rs index c4d623646..82c4c046f 100644 --- a/server/src/configs/system.rs +++ b/server/src/configs/system.rs @@ -1,5 +1,5 @@ -use crate::configs::compression_algorithm::CompressionAlgorithm; use crate::configs::resource_quota::MemoryResourceQuota; +use iggy::compression::CompressionKind; use serde::{Deserialize, Serialize}; #[derive(Debug, Deserialize, Serialize)] @@ -24,7 +24,7 @@ pub struct DatabaseConfig { #[derive(Debug, Deserialize, Serialize)] pub struct CompressionConfig { pub enabled: bool, - pub algorithm: CompressionAlgorithm, + pub algorithm: CompressionKind, } #[derive(Debug, Deserialize, Serialize)] From 69b9c6d549cdb20216e57d582988880bf0cac176 Mon Sep 17 00:00:00 2001 From: numinnex Date: Tue, 7 Nov 2023 16:48:26 +0100 Subject: [PATCH 5/6] Add negative case tests to CompressionKind conversion, enhance config with allow_override flag and improve from_str conversion --- configs/server.json | 4 ++-- configs/server.toml | 4 ++-- iggy/src/compression.rs | 26 +++++++++++++++++++++++--- server/src/configs/defaults.rs | 4 ++-- server/src/configs/displays.rs | 4 ++-- server/src/configs/system.rs | 4 ++-- server/src/configs/validators.rs | 18 ++++++++++++++++++ 7 files changed, 51 insertions(+), 13 deletions(-) diff --git a/configs/server.json b/configs/server.json index b05a694bd..82a597496 100644 --- a/configs/server.json +++ b/configs/server.json @@ -96,8 +96,8 @@ "key": "" }, "compression": { - "enabled": true, - "algorithm": "none" + "allow_override": false, + "default_algorithm": "none" }, "stream": { "path": "streams" diff --git a/configs/server.toml b/configs/server.toml index 338cd8d72..449b3920d 100644 --- a/configs/server.toml +++ b/configs/server.toml @@ -96,8 +96,8 @@ enabled = false key = "" [system.compression] -enabled = true -algorithm = "none" +allow_override = false +default_algorithm = "none" [system.stream] path = "streams" diff --git a/iggy/src/compression.rs b/iggy/src/compression.rs index d9f109933..a8f052def 100644 --- a/iggy/src/compression.rs +++ b/iggy/src/compression.rs @@ -21,9 +21,9 @@ impl FromStr for CompressionKind { type Err = String; fn from_str(s: &str) -> Result { - match s { - "Gzip" | "gzip" => Ok(CompressionKind::Gzip), - "None" | "none" => Ok(CompressionKind::None), + match s.to_lowercase().as_str() { + "gzip" => Ok(CompressionKind::Gzip), + "none" => Ok(CompressionKind::None), _ => Err(format!("Unknown compression type: {}", s)), } } @@ -124,6 +124,15 @@ mod tests { assert_eq!(gzip_alg.unwrap(), CompressionKind::Gzip); } + #[test] + fn test_from_invalid_input() { + let invalid_compression_kind = CompressionKind::from_str("invalid"); + assert!(invalid_compression_kind.is_err()); + + let invalid_compression_kind = CompressionKind::from_str("gzipp"); + assert!(invalid_compression_kind.is_err()); + } + #[test] fn test_into() { let none: CompressionKind = CompressionKind::None; @@ -156,4 +165,15 @@ mod tests { assert!(gzip.is_ok()); assert_eq!(gzip.unwrap(), CompressionKind::Gzip); } + #[test] + fn test_from_code_invalid_input() { + let invalid_compression_kind = CompressionKind::from_code(0); + assert!(invalid_compression_kind.is_err()); + + let invalid_compression_kind = CompressionKind::from_code(69); + assert!(invalid_compression_kind.is_err()); + + let invalid_compression_kind = CompressionKind::from_code(255); + assert!(invalid_compression_kind.is_err()); + } } diff --git a/server/src/configs/defaults.rs b/server/src/configs/defaults.rs index 4964537db..9d27b7dd9 100644 --- a/server/src/configs/defaults.rs +++ b/server/src/configs/defaults.rs @@ -142,8 +142,8 @@ impl Default for DatabaseConfig { impl Default for CompressionConfig { fn default() -> Self { CompressionConfig { - enabled: true, - algorithm: "none".parse().unwrap(), + allow_override: false, + default_algorithm: "none".parse().unwrap(), } } } diff --git a/server/src/configs/displays.rs b/server/src/configs/displays.rs index e6a1d3880..9c17256c8 100644 --- a/server/src/configs/displays.rs +++ b/server/src/configs/displays.rs @@ -104,8 +104,8 @@ impl Display for CompressionConfig { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!( f, - "{{ enabled: {}, algorithm: {} }}", - self.enabled, self.algorithm + "{{ allowed_override: {}, default_algorithm: {} }}", + self.allow_override, self.default_algorithm ) } } diff --git a/server/src/configs/system.rs b/server/src/configs/system.rs index 82c4c046f..09db7da26 100644 --- a/server/src/configs/system.rs +++ b/server/src/configs/system.rs @@ -23,8 +23,8 @@ pub struct DatabaseConfig { #[derive(Debug, Deserialize, Serialize)] pub struct CompressionConfig { - pub enabled: bool, - pub algorithm: CompressionKind, + pub allow_override: bool, + pub default_algorithm: CompressionKind, } #[derive(Debug, Deserialize, Serialize)] diff --git a/server/src/configs/validators.rs b/server/src/configs/validators.rs index aa07c5d26..b7c7dde81 100644 --- a/server/src/configs/validators.rs +++ b/server/src/configs/validators.rs @@ -1,11 +1,13 @@ extern crate sysinfo; use super::server::{MessageCleanerConfig, MessageSaverConfig}; +use super::system::CompressionConfig; use crate::configs::server::{PersonalAccessTokenConfig, ServerConfig}; use crate::configs::system::{CacheConfig, SegmentConfig}; use crate::server_error::ServerError; use crate::streaming::segments::segment; use byte_unit::{Byte, ByteUnit}; +use iggy::compression::CompressionKind; use iggy::validatable::Validatable; use sysinfo::SystemExt; use tracing::{error, info, warn}; @@ -14,12 +16,28 @@ impl Validatable for ServerConfig { fn validate(&self) -> Result<(), ServerError> { self.system.segment.validate()?; self.system.cache.validate()?; + self.system.compression.validate()?; self.personal_access_token.validate()?; Ok(()) } } +impl Validatable for CompressionConfig { + fn validate(&self) -> Result<(), ServerError> { + let compression_alg = self.default_algorithm.clone(); + if compression_alg != CompressionKind::None { + // TODO(numinex): Change this message once server side compression is fully developed. + warn!( + "Server started with server-side compression enabled, using algorithm: {}, this feature is not implemented yet!", + compression_alg + ); + } + + Ok(()) + } +} + impl Validatable for CacheConfig { fn validate(&self) -> Result<(), ServerError> { let limit_bytes = self.size.clone().into(); From 9ea0d03aa4661403902bcc5572ae4eaa588a1709 Mon Sep 17 00:00:00 2001 From: numinex Date: Tue, 7 Nov 2023 18:50:29 +0100 Subject: [PATCH 6/6] Rename CompressionKind to CompressionAlgorithm and remove not needed clone from CompressionConfig validate method --- .../compression_algorithm.rs} | 87 +++++++++---------- iggy/src/compression/mod.rs | 1 + server/src/configs/system.rs | 4 +- server/src/configs/validators.rs | 6 +- 4 files changed, 49 insertions(+), 49 deletions(-) rename iggy/src/{compression.rs => compression/compression_algorithm.rs} (52%) create mode 100644 iggy/src/compression/mod.rs diff --git a/iggy/src/compression.rs b/iggy/src/compression/compression_algorithm.rs similarity index 52% rename from iggy/src/compression.rs rename to iggy/src/compression/compression_algorithm.rs index a8f052def..5488f4dbe 100644 --- a/iggy/src/compression.rs +++ b/iggy/src/compression/compression_algorithm.rs @@ -12,73 +12,72 @@ use crate::error::Error; // for now only those, in the future will add snappy, lz4, zstd (same as in confluent kafka) in addition to that // we should consider brotli as well. #[derive(Debug, PartialEq, Clone)] -pub enum CompressionKind { +pub enum CompressionAlgorithm { None, Gzip, } - -impl FromStr for CompressionKind { +impl FromStr for CompressionAlgorithm { type Err = String; fn from_str(s: &str) -> Result { match s.to_lowercase().as_str() { - "gzip" => Ok(CompressionKind::Gzip), - "none" => Ok(CompressionKind::None), + "gzip" => Ok(CompressionAlgorithm::Gzip), + "none" => Ok(CompressionAlgorithm::None), _ => Err(format!("Unknown compression type: {}", s)), } } } -impl CompressionKind { +impl CompressionAlgorithm { pub fn as_code(&self) -> u8 { match self { - CompressionKind::None => 1, - CompressionKind::Gzip => 2, + CompressionAlgorithm::None => 1, + CompressionAlgorithm::Gzip => 2, } } pub fn from_code(code: u8) -> Result { match code { - 1 => Ok(CompressionKind::None), - 2 => Ok(CompressionKind::Gzip), + 1 => Ok(CompressionAlgorithm::None), + 2 => Ok(CompressionAlgorithm::Gzip), _ => Err(Error::InvalidCommand), } } } -impl Display for CompressionKind { +impl Display for CompressionAlgorithm { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - CompressionKind::None => write!(f, "none"), - CompressionKind::Gzip => write!(f, "gzip"), + CompressionAlgorithm::None => write!(f, "none"), + CompressionAlgorithm::Gzip => write!(f, "gzip"), } } } -impl Serialize for CompressionKind { +impl Serialize for CompressionAlgorithm { fn serialize(&self, serializer: S) -> Result where S: Serializer, { match self { - CompressionKind::None => serializer.serialize_str("none"), - CompressionKind::Gzip => serializer.serialize_str("gzip"), + CompressionAlgorithm::None => serializer.serialize_str("none"), + CompressionAlgorithm::Gzip => serializer.serialize_str("gzip"), } } } -impl From for String { - fn from(value: CompressionKind) -> Self { +impl From for String { + fn from(value: CompressionAlgorithm) -> Self { match value { - CompressionKind::None => "none".to_string(), - CompressionKind::Gzip => "gzip".to_string(), + CompressionAlgorithm::None => "none".to_string(), + CompressionAlgorithm::Gzip => "gzip".to_string(), } } } struct CompressionKindVisitor; impl<'de> Visitor<'de> for CompressionKindVisitor { - type Value = CompressionKind; + type Value = CompressionAlgorithm; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("a valid compression type, check documentation for more information.") @@ -88,11 +87,11 @@ impl<'de> Visitor<'de> for CompressionKindVisitor { where E: de::Error, { - CompressionKind::from_str(value).map_err(de::Error::custom) + CompressionAlgorithm::from_str(value).map_err(de::Error::custom) } } -impl<'de> Deserialize<'de> for CompressionKind { +impl<'de> Deserialize<'de> for CompressionAlgorithm { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, @@ -107,73 +106,73 @@ mod tests { #[test] fn test_from() { - let none_alg = CompressionKind::from_str("none"); + let none_alg = CompressionAlgorithm::from_str("none"); assert!(none_alg.is_ok()); - assert_eq!(none_alg.unwrap(), CompressionKind::None); + assert_eq!(none_alg.unwrap(), CompressionAlgorithm::None); - let none_alg = CompressionKind::from_str("None"); + let none_alg = CompressionAlgorithm::from_str("None"); assert!(none_alg.is_ok()); - assert_eq!(none_alg.unwrap(), CompressionKind::None); + assert_eq!(none_alg.unwrap(), CompressionAlgorithm::None); - let gzip_alg = CompressionKind::from_str("gzip"); + let gzip_alg = CompressionAlgorithm::from_str("gzip"); assert!(gzip_alg.is_ok()); - assert_eq!(gzip_alg.unwrap(), CompressionKind::Gzip); + assert_eq!(gzip_alg.unwrap(), CompressionAlgorithm::Gzip); - let gzip_alg = CompressionKind::from_str("Gzip"); + let gzip_alg = CompressionAlgorithm::from_str("Gzip"); assert!(gzip_alg.is_ok()); - assert_eq!(gzip_alg.unwrap(), CompressionKind::Gzip); + assert_eq!(gzip_alg.unwrap(), CompressionAlgorithm::Gzip); } #[test] fn test_from_invalid_input() { - let invalid_compression_kind = CompressionKind::from_str("invalid"); + let invalid_compression_kind = CompressionAlgorithm::from_str("invalid"); assert!(invalid_compression_kind.is_err()); - let invalid_compression_kind = CompressionKind::from_str("gzipp"); + let invalid_compression_kind = CompressionAlgorithm::from_str("gzipp"); assert!(invalid_compression_kind.is_err()); } #[test] fn test_into() { - let none: CompressionKind = CompressionKind::None; + let none: CompressionAlgorithm = CompressionAlgorithm::None; let none_string: String = none.into(); assert_eq!(none_string, "none".to_string()); - let gzip: CompressionKind = CompressionKind::Gzip; + let gzip: CompressionAlgorithm = CompressionAlgorithm::Gzip; let gzip_string: String = gzip.into(); assert_eq!(gzip_string, "gzip".to_string()); } #[test] fn test_as_code() { - let none = CompressionKind::None; + let none = CompressionAlgorithm::None; let none_code = none.as_code(); assert_eq!(none_code, 1); - let gzip = CompressionKind::Gzip; + let gzip = CompressionAlgorithm::Gzip; let gzip_code = gzip.as_code(); assert_eq!(gzip_code, 2); } #[test] fn test_from_code() { - let none = CompressionKind::from_code(1); + let none = CompressionAlgorithm::from_code(1); assert!(none.is_ok()); - assert_eq!(none.unwrap(), CompressionKind::None); + assert_eq!(none.unwrap(), CompressionAlgorithm::None); - let gzip = CompressionKind::from_code(2); + let gzip = CompressionAlgorithm::from_code(2); assert!(gzip.is_ok()); - assert_eq!(gzip.unwrap(), CompressionKind::Gzip); + assert_eq!(gzip.unwrap(), CompressionAlgorithm::Gzip); } #[test] fn test_from_code_invalid_input() { - let invalid_compression_kind = CompressionKind::from_code(0); + let invalid_compression_kind = CompressionAlgorithm::from_code(0); assert!(invalid_compression_kind.is_err()); - let invalid_compression_kind = CompressionKind::from_code(69); + let invalid_compression_kind = CompressionAlgorithm::from_code(69); assert!(invalid_compression_kind.is_err()); - let invalid_compression_kind = CompressionKind::from_code(255); + let invalid_compression_kind = CompressionAlgorithm::from_code(255); assert!(invalid_compression_kind.is_err()); } } diff --git a/iggy/src/compression/mod.rs b/iggy/src/compression/mod.rs new file mode 100644 index 000000000..3f5760c9a --- /dev/null +++ b/iggy/src/compression/mod.rs @@ -0,0 +1 @@ +pub mod compression_algorithm; diff --git a/server/src/configs/system.rs b/server/src/configs/system.rs index 09db7da26..b508ebe80 100644 --- a/server/src/configs/system.rs +++ b/server/src/configs/system.rs @@ -1,5 +1,5 @@ use crate::configs::resource_quota::MemoryResourceQuota; -use iggy::compression::CompressionKind; +use iggy::compression::compression_algorithm::CompressionAlgorithm; use serde::{Deserialize, Serialize}; #[derive(Debug, Deserialize, Serialize)] @@ -24,7 +24,7 @@ pub struct DatabaseConfig { #[derive(Debug, Deserialize, Serialize)] pub struct CompressionConfig { pub allow_override: bool, - pub default_algorithm: CompressionKind, + pub default_algorithm: CompressionAlgorithm, } #[derive(Debug, Deserialize, Serialize)] diff --git a/server/src/configs/validators.rs b/server/src/configs/validators.rs index b7c7dde81..41728e563 100644 --- a/server/src/configs/validators.rs +++ b/server/src/configs/validators.rs @@ -7,7 +7,7 @@ use crate::configs::system::{CacheConfig, SegmentConfig}; use crate::server_error::ServerError; use crate::streaming::segments::segment; use byte_unit::{Byte, ByteUnit}; -use iggy::compression::CompressionKind; +use iggy::compression::compression_algorithm::CompressionAlgorithm; use iggy::validatable::Validatable; use sysinfo::SystemExt; use tracing::{error, info, warn}; @@ -25,8 +25,8 @@ impl Validatable for ServerConfig { impl Validatable for CompressionConfig { fn validate(&self) -> Result<(), ServerError> { - let compression_alg = self.default_algorithm.clone(); - if compression_alg != CompressionKind::None { + let compression_alg = &self.default_algorithm; + if *compression_alg != CompressionAlgorithm::None { // TODO(numinex): Change this message once server side compression is fully developed. warn!( "Server started with server-side compression enabled, using algorithm: {}, this feature is not implemented yet!",