This is an automated email from the ASF dual-hosted git repository.

piotr pushed a commit to branch update_hash
in repository https://gitbox.apache.org/repos/asf/iggy.git

commit a952ce86d2adb39891b2227a6783b58f9ab9683b
Author: spetz <[email protected]>
AuthorDate: Wed Nov 12 21:29:10 2025 +0100

    Allow passing numeric or string identifier in request body
---
 core/common/src/types/consumer/consumer_kind.rs | 82 +++++++++++++++++++++++--
 core/server/server.http                         |  1 -
 2 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/core/common/src/types/consumer/consumer_kind.rs 
b/core/common/src/types/consumer/consumer_kind.rs
index af0534d62..65a4ffd3e 100644
--- a/core/common/src/types/consumer/consumer_kind.rs
+++ b/core/common/src/types/consumer/consumer_kind.rs
@@ -22,16 +22,15 @@ use crate::Validatable;
 use crate::error::IggyError;
 use bytes::{BufMut, Bytes, BytesMut};
 use clap::ValueEnum;
-use serde::{Deserialize, Serialize};
-use serde_with::{DisplayFromStr, serde_as};
+use serde::{Deserialize, Deserializer, Serialize};
 use std::fmt::Display;
+use std::str::FromStr;
 
 /// `Consumer` represents the type of consumer that is consuming a message.
 /// It can be either a `Consumer` or a `ConsumerGroup`.
 /// It consists of the following fields:
 /// - `kind`: the type of consumer. It can be either `Consumer` or 
`ConsumerGroup`.
 /// - `id`: the unique identifier of the consumer.
-#[serde_as]
 #[derive(Debug, Serialize, Deserialize, PartialEq, Default, Clone)]
 pub struct Consumer {
     /// The type of consumer. It can be either `Consumer` or `ConsumerGroup`.
@@ -39,7 +38,8 @@ pub struct Consumer {
     pub kind: ConsumerKind,
     /// The unique identifier of the consumer.
     #[serde(rename = "consumer_id")]
-    #[serde_as(as = "DisplayFromStr")]
+    #[serde(serialize_with = "serialize_identifier")]
+    #[serde(deserialize_with = "deserialize_identifier")]
     #[serde(default = "default_id")]
     pub id: Identifier,
 }
@@ -152,3 +152,77 @@ impl Display for ConsumerKind {
         }
     }
 }
+
+fn serialize_identifier<S>(id: &Identifier, serializer: S) -> Result<S::Ok, 
S::Error>
+where
+    S: serde::Serializer,
+{
+    serializer.serialize_str(&id.to_string())
+}
+
+fn deserialize_identifier<'de, D>(deserializer: D) -> Result<Identifier, 
D::Error>
+where
+    D: Deserializer<'de>,
+{
+    struct IdentifierVisitor;
+
+    impl<'de> serde::de::Visitor<'de> for IdentifierVisitor {
+        type Value = Identifier;
+
+        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> 
std::fmt::Result {
+            formatter.write_str("a string or number representing an 
identifier")
+        }
+
+        fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+        where
+            E: serde::de::Error,
+        {
+            Identifier::from_str(value).map_err(serde::de::Error::custom)
+        }
+
+        fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
+        where
+            E: serde::de::Error,
+        {
+            Identifier::numeric(value).map_err(serde::de::Error::custom)
+        }
+
+        fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
+        where
+            E: serde::de::Error,
+        {
+            if value > u32::MAX as u64 {
+                return Err(serde::de::Error::custom(
+                    "numeric identifier must fit in u32",
+                ));
+            }
+            Identifier::numeric(value as u32).map_err(serde::de::Error::custom)
+        }
+
+        fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
+        where
+            E: serde::de::Error,
+        {
+            if value < 0 {
+                return Err(serde::de::Error::custom(
+                    "numeric identifier must be positive",
+                ));
+            }
+            Identifier::numeric(value as u32).map_err(serde::de::Error::custom)
+        }
+
+        fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
+        where
+            E: serde::de::Error,
+        {
+            if value < 0 || value > u32::MAX as i64 {
+                return Err(serde::de::Error::custom(
+                    "numeric identifier must be a positive u32",
+                ));
+            }
+            Identifier::numeric(value as u32).map_err(serde::de::Error::custom)
+        }
+    }
+
+    deserializer.deserialize_any(IdentifierVisitor)
+}
diff --git a/core/server/server.http b/core/server/server.http
index 02bd5c1e1..f9e49908d 100644
--- a/core/server/server.http
+++ b/core/server/server.http
@@ -344,7 +344,6 @@ Authorization: Bearer {{access_token}}
 Content-Type: application/json
 
 {
-  "consumer_group_id": {{consumer_group_id}},
   "name": "consumer_group_1"
 }
 

Reply via email to