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

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


The following commit(s) were added to refs/heads/non_string_header_key by this 
push:
     new b6d590482 Refactor user headers to be idimomatic
b6d590482 is described below

commit b6d590482cda54d0a68fe7e62a8c1e9aa704748a
Author: spetz <[email protected]>
AuthorDate: Thu Jan 29 20:22:02 2026 +0100

    Refactor user headers to be idimomatic
---
 core/cli/src/args/message.rs                       |   61 +-
 core/common/src/types/message/iggy_message.rs      |   22 +-
 core/common/src/types/message/user_headers.rs      | 1273 ++++++++++++--------
 .../tests/cli/message/test_message_poll_command.rs |    5 +-
 .../tests/cli/message/test_message_send_command.rs |   13 +-
 .../server/scenarios/create_message_payload.rs     |   21 +-
 .../tests/server/scenarios/encryption_scenario.rs  |   54 +-
 .../server/scenarios/message_headers_scenario.rs   |   21 +-
 .../server/scenarios/message_size_scenario.rs      |    5 +-
 .../tests/server/scenarios/offset_scenario.rs      |   15 +-
 .../tests/server/scenarios/timestamp_scenario.rs   |   15 +-
 core/sdk/src/prelude.rs                            |   12 +-
 core/server/server.http                            |   26 +-
 core/tools/src/data-seeder/seeder.rs               |   15 +-
 .../message-headers/message-type/consumer/main.rs  |    2 +-
 .../message-headers/message-type/producer/main.rs  |    5 +-
 .../message-headers/typed-headers/producer/main.rs |   26 +-
 examples/rust/src/shared/codec.rs                  |    4 +-
 .../Iggy_SDK/JsonConverters/MessageConverter.cs    |    4 +-
 19 files changed, 922 insertions(+), 677 deletions(-)

diff --git a/core/cli/src/args/message.rs b/core/cli/src/args/message.rs
index da5e742e6..5157722fe 100644
--- a/core/cli/src/args/message.rs
+++ b/core/cli/src/args/message.rs
@@ -128,7 +128,66 @@ fn parse_key_val(s: &str) -> Result<(HeaderKey, 
HeaderValue), IggyError> {
     }
 
     let key = HeaderKey::from_str(parts[0])?;
-    let value = HeaderValue::from_kind_str_and_value_str(parts[1], parts[2])?;
+    let kind = HeaderKind::from_str(parts[1])?;
+    let value_str = parts[2];
+
+    let value = match kind {
+        HeaderKind::Raw => HeaderValue::try_from(value_str.as_bytes())?,
+        HeaderKind::String => HeaderValue::try_from(value_str)?,
+        HeaderKind::Bool => value_str
+            .parse::<bool>()
+            .map_err(|_| IggyError::InvalidBooleanValue)?
+            .into(),
+        HeaderKind::Int8 => value_str
+            .parse::<i8>()
+            .map_err(|_| IggyError::InvalidNumberValue)?
+            .into(),
+        HeaderKind::Int16 => value_str
+            .parse::<i16>()
+            .map_err(|_| IggyError::InvalidNumberValue)?
+            .into(),
+        HeaderKind::Int32 => value_str
+            .parse::<i32>()
+            .map_err(|_| IggyError::InvalidNumberValue)?
+            .into(),
+        HeaderKind::Int64 => value_str
+            .parse::<i64>()
+            .map_err(|_| IggyError::InvalidNumberValue)?
+            .into(),
+        HeaderKind::Int128 => value_str
+            .parse::<i128>()
+            .map_err(|_| IggyError::InvalidNumberValue)?
+            .into(),
+        HeaderKind::Uint8 => value_str
+            .parse::<u8>()
+            .map_err(|_| IggyError::InvalidNumberValue)?
+            .into(),
+        HeaderKind::Uint16 => value_str
+            .parse::<u16>()
+            .map_err(|_| IggyError::InvalidNumberValue)?
+            .into(),
+        HeaderKind::Uint32 => value_str
+            .parse::<u32>()
+            .map_err(|_| IggyError::InvalidNumberValue)?
+            .into(),
+        HeaderKind::Uint64 => value_str
+            .parse::<u64>()
+            .map_err(|_| IggyError::InvalidNumberValue)?
+            .into(),
+        HeaderKind::Uint128 => value_str
+            .parse::<u128>()
+            .map_err(|_| IggyError::InvalidNumberValue)?
+            .into(),
+        HeaderKind::Float32 => value_str
+            .parse::<f32>()
+            .map_err(|_| IggyError::InvalidNumberValue)?
+            .into(),
+        HeaderKind::Float64 => value_str
+            .parse::<f64>()
+            .map_err(|_| IggyError::InvalidNumberValue)?
+            .into(),
+    };
+
     Ok((key, value))
 }
 
diff --git a/core/common/src/types/message/iggy_message.rs 
b/core/common/src/types/message/iggy_message.rs
index 5bc464fc1..f34b2b272 100644
--- a/core/common/src/types/message/iggy_message.rs
+++ b/core/common/src/types/message/iggy_message.rs
@@ -680,8 +680,8 @@ mod tests {
     fn test_create_with_headers() {
         let mut headers = HashMap::new();
         headers.insert(
-            HeaderKey::from_string("content-type").unwrap(),
-            HeaderValue::from_str("text/plain").unwrap(),
+            HeaderKey::try_from("content-type").unwrap(),
+            HeaderValue::try_from("text/plain").unwrap(),
         );
 
         let message = IggyMessage::builder()
@@ -694,7 +694,7 @@ mod tests {
 
         let headers_map = message.user_headers_map().unwrap().unwrap();
         assert_eq!(headers_map.len(), 1);
-        
assert!(headers_map.contains_key(&HeaderKey::from_string("content-type").unwrap()));
+        
assert!(headers_map.contains_key(&HeaderKey::try_from("content-type").unwrap()));
     }
 
     #[test]
@@ -736,12 +736,12 @@ mod tests {
     fn test_json_serialization_with_headers() {
         let mut headers = HashMap::new();
         headers.insert(
-            HeaderKey::from_string("content-type").unwrap(),
-            HeaderValue::from_str("text/plain").unwrap(),
+            HeaderKey::try_from("content-type").unwrap(),
+            HeaderValue::try_from("text/plain").unwrap(),
         );
         headers.insert(
-            HeaderKey::from_string("correlation-id").unwrap(),
-            HeaderValue::from_str("123456").unwrap(),
+            HeaderKey::try_from("correlation-id").unwrap(),
+            HeaderValue::try_from("123456").unwrap(),
         );
 
         let original = IggyMessage::builder()
@@ -785,12 +785,12 @@ mod tests {
 
         assert_eq!(original_map.len(), deserialized_map.len());
         assert_eq!(
-            original_map.get(&HeaderKey::from_string("content-type").unwrap()),
-            
deserialized_map.get(&HeaderKey::from_string("content-type").unwrap())
+            original_map.get(&HeaderKey::try_from("content-type").unwrap()),
+            deserialized_map.get(&HeaderKey::try_from("content-type").unwrap())
         );
         assert_eq!(
-            
original_map.get(&HeaderKey::from_string("correlation-id").unwrap()),
-            
deserialized_map.get(&HeaderKey::from_string("correlation-id").unwrap())
+            original_map.get(&HeaderKey::try_from("correlation-id").unwrap()),
+            
deserialized_map.get(&HeaderKey::try_from("correlation-id").unwrap())
         );
     }
 }
diff --git a/core/common/src/types/message/user_headers.rs 
b/core/common/src/types/message/user_headers.rs
index 3912fd88f..6efaf1054 100644
--- a/core/common/src/types/message/user_headers.rs
+++ b/core/common/src/types/message/user_headers.rs
@@ -28,8 +28,63 @@ use std::hash::{Hash, Hasher};
 use std::marker::PhantomData;
 use std::str::FromStr;
 
+/// Type alias for header keys in user-defined message headers.
+///
+/// Header keys can be created from various types using `From`/`TryFrom` 
traits:
+/// - Fixed-size types (infallible): `bool`, `i8`-`i128`, `u8`-`u128`, `f32`, 
`f64`
+/// - Variable-size types (fallible, max 255 bytes): `&str`, `String`, 
`&[u8]`, `Vec<u8>`
+///
+/// Values can be extracted back using `TryFrom` or `as_*` methods.
+///
+/// # Examples
+///
+/// ```
+/// use iggy_common::{HeaderKey, HeaderValue, IggyError};
+///
+/// // Create from string (most common)
+/// let key = HeaderKey::try_from("content-type")?;
+///
+/// // Create from integer (for numeric keys)
+/// let key: HeaderKey = 42u32.into();
+///
+/// // Extract value back
+/// let num: u32 = key.try_into()?;
+/// assert_eq!(num, 42);
+/// # Ok::<(), IggyError>(())
+/// ```
 pub type HeaderKey = HeaderField<KeyMarker>;
+
+/// Type alias for header values in user-defined message headers.
+///
+/// Header values can be created from various types using `From`/`TryFrom` 
traits:
+/// - Fixed-size types (infallible): `bool`, `i8`-`i128`, `u8`-`u128`, `f32`, 
`f64`
+/// - Variable-size types (fallible, max 255 bytes): `&str`, `String`, 
`&[u8]`, `Vec<u8>`
+///
+/// Values can be extracted back using `TryFrom` or `as_*` methods.
+///
+/// # Examples
+///
+/// ```
+/// use iggy_common::{HeaderKey, HeaderValue, IggyError};
+///
+/// // Create from various types
+/// let str_val = HeaderValue::try_from("text/plain")?;
+/// let int_val: HeaderValue = 42i32.into();
+/// let bool_val: HeaderValue = true.into();
+/// let float_val: HeaderValue = 3.14f64.into();
+///
+/// // Extract values back using TryFrom
+/// let num: i32 = int_val.try_into()?;
+/// assert_eq!(num, 42);
+///
+/// // Or use as_* methods
+/// let str_val = HeaderValue::try_from("hello")?;
+/// assert_eq!(str_val.as_str()?, "hello");
+/// # Ok::<(), IggyError>(())
+/// ```
 pub type HeaderValue = HeaderField<ValueMarker>;
+
+/// Type alias for a collection of user-defined message headers.
 pub type UserHeaders = HashMap<HeaderKey, HeaderValue>;
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -38,33 +93,124 @@ pub struct KeyMarker;
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct ValueMarker;
 
+/// A typed header field that can be used as either a key or value in message 
headers.
+///
+/// `HeaderField` is a generic struct parameterized by a marker type 
(`KeyMarker` or `ValueMarker`)
+/// to distinguish between keys and values at the type level. Use the type 
aliases
+/// [`HeaderKey`] and [`HeaderValue`] instead of using this struct directly.
+///
+/// # Creating Header Fields
+///
+/// Use `From` trait for fixed-size types (infallible):
+/// ```
+/// use iggy_common::HeaderValue;
+///
+/// let val: HeaderValue = 42i32.into();
+/// let val: HeaderValue = true.into();
+/// let val: HeaderValue = 3.14f64.into();
+/// ```
+///
+/// Use `TryFrom` trait for variable-size types (fallible, max 255 bytes):
+/// ```
+/// use iggy_common::{HeaderValue, IggyError};
+///
+/// let val = HeaderValue::try_from("hello")?;
+/// let val = HeaderValue::try_from(vec![1u8, 2, 3])?;
+/// # Ok::<(), IggyError>(())
+/// ```
+///
+/// # Extracting Values
+///
+/// Use `TryFrom` to extract values (returns error if kind doesn't match):
+/// ```
+/// use iggy_common::{HeaderValue, IggyError};
+///
+/// let val: HeaderValue = 42i32.into();
+/// let num: i32 = val.try_into()?;
+///
+/// // Using reference to avoid consuming the value
+/// let val: HeaderValue = 100u64.into();
+/// let num: u64 = (&val).try_into()?;
+/// // val is still usable here
+/// # Ok::<(), IggyError>(())
+/// ```
+///
+/// Or use `as_*` methods:
+/// ```
+/// use iggy_common::{HeaderValue, IggyError};
+///
+/// let val: HeaderValue = 42i32.into();
+/// assert_eq!(val.as_int32()?, 42);
+/// # Ok::<(), IggyError>(())
+/// ```
 #[serde_as]
 #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
 pub struct HeaderField<T> {
+    /// The type of value stored in this header field.
     pub kind: HeaderKind,
+    /// The raw bytes of the value, encoded according to `kind`.
     #[serde_as(as = "Base64")]
     pub value: Bytes,
     #[serde(skip)]
     _marker: PhantomData<T>,
 }
 
+/// Indicates the type of value stored in a [`HeaderField`].
+///
+/// This enum is used to track what type of data is stored in the header's raw 
bytes,
+/// enabling proper deserialization and type checking when extracting values.
+///
+/// # Supported Types
+///
+/// | Kind | Rust Type | Size (bytes) |
+/// |------|-----------|--------------|
+/// | `Raw` | `&[u8]` / `Vec<u8>` | 1-255 |
+/// | `String` | `&str` / `String` | 1-255 |
+/// | `Bool` | `bool` | 1 |
+/// | `Int8` | `i8` | 1 |
+/// | `Int16` | `i16` | 2 |
+/// | `Int32` | `i32` | 4 |
+/// | `Int64` | `i64` | 8 |
+/// | `Int128` | `i128` | 16 |
+/// | `Uint8` | `u8` | 1 |
+/// | `Uint16` | `u16` | 2 |
+/// | `Uint32` | `u32` | 4 |
+/// | `Uint64` | `u64` | 8 |
+/// | `Uint128` | `u128` | 16 |
+/// | `Float32` | `f32` | 4 |
+/// | `Float64` | `f64` | 8 |
 #[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Hash)]
 #[serde(rename_all = "snake_case")]
 pub enum HeaderKind {
+    /// Raw binary data.
     Raw,
+    /// UTF-8 encoded string.
     String,
+    /// Boolean value.
     Bool,
+    /// Signed 8-bit integer.
     Int8,
+    /// Signed 16-bit integer.
     Int16,
+    /// Signed 32-bit integer.
     Int32,
+    /// Signed 64-bit integer.
     Int64,
+    /// Signed 128-bit integer.
     Int128,
+    /// Unsigned 8-bit integer.
     Uint8,
+    /// Unsigned 16-bit integer.
     Uint16,
+    /// Unsigned 32-bit integer.
     Uint32,
+    /// Unsigned 64-bit integer.
     Uint64,
+    /// Unsigned 128-bit integer.
     Uint128,
+    /// 32-bit floating point number.
     Float32,
+    /// 64-bit floating point number.
     Float64,
 }
 
@@ -174,73 +320,11 @@ impl<T> Hash for HeaderField<T> {
 impl<T> FromStr for HeaderField<T> {
     type Err = IggyError;
     fn from_str(s: &str) -> Result<Self, Self::Err> {
-        Self::from_string(s)
-    }
-}
-
-impl<T> TryFrom<&str> for HeaderField<T> {
-    type Error = IggyError;
-    fn try_from(value: &str) -> Result<Self, Self::Error> {
-        Self::from_string(value)
+        Self::try_from(s)
     }
 }
 
 impl<T> HeaderField<T> {
-    pub fn from_kind_str_and_value_str(kind: &str, value: &str) -> 
Result<Self, IggyError> {
-        let kind = HeaderKind::from_str(kind)?;
-        Self::from_kind_and_value_str(kind, value)
-    }
-
-    pub fn from_kind_and_value_str(kind: HeaderKind, value: &str) -> 
Result<Self, IggyError> {
-        match kind {
-            HeaderKind::Raw => Self::from_raw(value.as_bytes()),
-            HeaderKind::String => Self::from_string(value),
-            HeaderKind::Bool => {
-                Self::from_bool(value.parse().map_err(|_| 
IggyError::InvalidBooleanValue)?)
-            }
-            HeaderKind::Int8 => {
-                Self::from_int8(value.parse().map_err(|_| 
IggyError::InvalidNumberValue)?)
-            }
-            HeaderKind::Int16 => {
-                Self::from_int16(value.parse().map_err(|_| 
IggyError::InvalidNumberValue)?)
-            }
-            HeaderKind::Int32 => {
-                Self::from_int32(value.parse().map_err(|_| 
IggyError::InvalidNumberValue)?)
-            }
-            HeaderKind::Int64 => {
-                Self::from_int64(value.parse().map_err(|_| 
IggyError::InvalidNumberValue)?)
-            }
-            HeaderKind::Int128 => {
-                Self::from_int128(value.parse().map_err(|_| 
IggyError::InvalidNumberValue)?)
-            }
-            HeaderKind::Uint8 => {
-                Self::from_uint8(value.parse().map_err(|_| 
IggyError::InvalidNumberValue)?)
-            }
-            HeaderKind::Uint16 => {
-                Self::from_uint16(value.parse().map_err(|_| 
IggyError::InvalidNumberValue)?)
-            }
-            HeaderKind::Uint32 => {
-                Self::from_uint32(value.parse().map_err(|_| 
IggyError::InvalidNumberValue)?)
-            }
-            HeaderKind::Uint64 => {
-                Self::from_uint64(value.parse().map_err(|_| 
IggyError::InvalidNumberValue)?)
-            }
-            HeaderKind::Uint128 => {
-                Self::from_uint128(value.parse().map_err(|_| 
IggyError::InvalidNumberValue)?)
-            }
-            HeaderKind::Float32 => {
-                Self::from_float32(value.parse().map_err(|_| 
IggyError::InvalidNumberValue)?)
-            }
-            HeaderKind::Float64 => {
-                Self::from_float64(value.parse().map_err(|_| 
IggyError::InvalidNumberValue)?)
-            }
-        }
-    }
-
-    pub fn from_raw(value: &[u8]) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Raw, value)
-    }
-
     pub fn as_raw(&self) -> Result<&[u8], IggyError> {
         if self.kind != HeaderKind::Raw {
             return Err(IggyError::InvalidHeaderValue);
@@ -248,10 +332,6 @@ impl<T> HeaderField<T> {
         Ok(&self.value)
     }
 
-    pub fn from_string(value: &str) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::String, value.as_bytes())
-    }
-
     pub fn as_str(&self) -> Result<&str, IggyError> {
         if self.kind != HeaderKind::String {
             return Err(IggyError::InvalidHeaderValue);
@@ -259,10 +339,6 @@ impl<T> HeaderField<T> {
         std::str::from_utf8(&self.value).map_err(|_| IggyError::InvalidUtf8)
     }
 
-    pub fn from_bool(value: bool) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Bool, if value { &[1] } else { &[0] })
-    }
-
     pub fn as_bool(&self) -> Result<bool, IggyError> {
         if self.kind != HeaderKind::Bool {
             return Err(IggyError::InvalidHeaderValue);
@@ -274,83 +350,59 @@ impl<T> HeaderField<T> {
         }
     }
 
-    pub fn from_int8(value: i8) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Int8, &value.to_le_bytes())
-    }
-
     pub fn as_int8(&self) -> Result<i8, IggyError> {
         if self.kind != HeaderKind::Int8 {
             return Err(IggyError::InvalidHeaderValue);
         }
-        let value = self.value.to_vec().try_into();
-        if value.is_err() {
-            return Err(IggyError::InvalidHeaderValue);
-        }
-        Ok(i8::from_le_bytes(value.unwrap()))
-    }
-
-    pub fn from_int16(value: i16) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Int16, &value.to_le_bytes())
+        self.value
+            .as_ref()
+            .try_into()
+            .map(i8::from_le_bytes)
+            .map_err(|_| IggyError::InvalidHeaderValue)
     }
 
     pub fn as_int16(&self) -> Result<i16, IggyError> {
         if self.kind != HeaderKind::Int16 {
             return Err(IggyError::InvalidHeaderValue);
         }
-        let value = self.value.to_vec().try_into();
-        if value.is_err() {
-            return Err(IggyError::InvalidHeaderValue);
-        }
-        Ok(i16::from_le_bytes(value.unwrap()))
-    }
-
-    pub fn from_int32(value: i32) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Int32, &value.to_le_bytes())
+        self.value
+            .as_ref()
+            .try_into()
+            .map(i16::from_le_bytes)
+            .map_err(|_| IggyError::InvalidHeaderValue)
     }
 
     pub fn as_int32(&self) -> Result<i32, IggyError> {
         if self.kind != HeaderKind::Int32 {
             return Err(IggyError::InvalidHeaderValue);
         }
-        let value = self.value.to_vec().try_into();
-        if value.is_err() {
-            return Err(IggyError::InvalidHeaderValue);
-        }
-        Ok(i32::from_le_bytes(value.unwrap()))
-    }
-
-    pub fn from_int64(value: i64) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Int64, &value.to_le_bytes())
+        self.value
+            .as_ref()
+            .try_into()
+            .map(i32::from_le_bytes)
+            .map_err(|_| IggyError::InvalidHeaderValue)
     }
 
     pub fn as_int64(&self) -> Result<i64, IggyError> {
         if self.kind != HeaderKind::Int64 {
             return Err(IggyError::InvalidHeaderValue);
         }
-        let value = self.value.to_vec().try_into();
-        if value.is_err() {
-            return Err(IggyError::InvalidHeaderValue);
-        }
-        Ok(i64::from_le_bytes(value.unwrap()))
-    }
-
-    pub fn from_int128(value: i128) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Int128, &value.to_le_bytes())
+        self.value
+            .as_ref()
+            .try_into()
+            .map(i64::from_le_bytes)
+            .map_err(|_| IggyError::InvalidHeaderValue)
     }
 
     pub fn as_int128(&self) -> Result<i128, IggyError> {
         if self.kind != HeaderKind::Int128 {
             return Err(IggyError::InvalidHeaderValue);
         }
-        let value = self.value.to_vec().try_into();
-        if value.is_err() {
-            return Err(IggyError::InvalidHeaderValue);
-        }
-        Ok(i128::from_le_bytes(value.unwrap()))
-    }
-
-    pub fn from_uint8(value: u8) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Uint8, &value.to_le_bytes())
+        self.value
+            .as_ref()
+            .try_into()
+            .map(i128::from_le_bytes)
+            .map_err(|_| IggyError::InvalidHeaderValue)
     }
 
     pub fn as_uint8(&self) -> Result<u8, IggyError> {
@@ -360,94 +412,70 @@ impl<T> HeaderField<T> {
         Ok(self.value[0])
     }
 
-    pub fn from_uint16(value: u16) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Uint16, &value.to_le_bytes())
-    }
-
     pub fn as_uint16(&self) -> Result<u16, IggyError> {
         if self.kind != HeaderKind::Uint16 {
             return Err(IggyError::InvalidHeaderValue);
         }
-        let value = self.value.to_vec().try_into();
-        if value.is_err() {
-            return Err(IggyError::InvalidHeaderValue);
-        }
-        Ok(u16::from_le_bytes(value.unwrap()))
-    }
-
-    pub fn from_uint32(value: u32) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Uint32, &value.to_le_bytes())
+        self.value
+            .as_ref()
+            .try_into()
+            .map(u16::from_le_bytes)
+            .map_err(|_| IggyError::InvalidHeaderValue)
     }
 
     pub fn as_uint32(&self) -> Result<u32, IggyError> {
         if self.kind != HeaderKind::Uint32 {
             return Err(IggyError::InvalidHeaderValue);
         }
-        let value = self.value.to_vec().try_into();
-        if value.is_err() {
-            return Err(IggyError::InvalidHeaderValue);
-        }
-        Ok(u32::from_le_bytes(value.unwrap()))
-    }
-
-    pub fn from_uint64(value: u64) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Uint64, &value.to_le_bytes())
+        self.value
+            .as_ref()
+            .try_into()
+            .map(u32::from_le_bytes)
+            .map_err(|_| IggyError::InvalidHeaderValue)
     }
 
     pub fn as_uint64(&self) -> Result<u64, IggyError> {
         if self.kind != HeaderKind::Uint64 {
             return Err(IggyError::InvalidHeaderValue);
         }
-        let value = self.value.to_vec().try_into();
-        if value.is_err() {
-            return Err(IggyError::InvalidHeaderValue);
-        }
-        Ok(u64::from_le_bytes(value.unwrap()))
-    }
-
-    pub fn from_uint128(value: u128) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Uint128, &value.to_le_bytes())
+        self.value
+            .as_ref()
+            .try_into()
+            .map(u64::from_le_bytes)
+            .map_err(|_| IggyError::InvalidHeaderValue)
     }
 
     pub fn as_uint128(&self) -> Result<u128, IggyError> {
         if self.kind != HeaderKind::Uint128 {
             return Err(IggyError::InvalidHeaderValue);
         }
-        let value = self.value.to_vec().try_into();
-        if value.is_err() {
-            return Err(IggyError::InvalidHeaderValue);
-        }
-        Ok(u128::from_le_bytes(value.unwrap()))
-    }
-
-    pub fn from_float32(value: f32) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Float32, &value.to_le_bytes())
+        self.value
+            .as_ref()
+            .try_into()
+            .map(u128::from_le_bytes)
+            .map_err(|_| IggyError::InvalidHeaderValue)
     }
 
     pub fn as_float32(&self) -> Result<f32, IggyError> {
         if self.kind != HeaderKind::Float32 {
             return Err(IggyError::InvalidHeaderValue);
         }
-        let value = self.value.to_vec().try_into();
-        if value.is_err() {
-            return Err(IggyError::InvalidHeaderValue);
-        }
-        Ok(f32::from_le_bytes(value.unwrap()))
-    }
-
-    pub fn from_float64(value: f64) -> Result<Self, IggyError> {
-        Self::from(HeaderKind::Float64, &value.to_le_bytes())
+        self.value
+            .as_ref()
+            .try_into()
+            .map(f32::from_le_bytes)
+            .map_err(|_| IggyError::InvalidHeaderValue)
     }
 
     pub fn as_float64(&self) -> Result<f64, IggyError> {
         if self.kind != HeaderKind::Float64 {
             return Err(IggyError::InvalidHeaderValue);
         }
-        let value = self.value.to_vec().try_into();
-        if value.is_err() {
-            return Err(IggyError::InvalidHeaderValue);
-        }
-        Ok(f64::from_le_bytes(value.unwrap()))
+        self.value
+            .as_ref()
+            .try_into()
+            .map(f64::from_le_bytes)
+            .map_err(|_| IggyError::InvalidHeaderValue)
     }
 
     pub fn to_string_value(&self) -> String {
@@ -457,64 +485,383 @@ impl<T> HeaderField<T> {
             HeaderKind::Bool => format!("{}", self.value[0] != 0),
             HeaderKind::Int8 => format!(
                 "{}",
-                i8::from_le_bytes(self.value.to_vec().try_into().unwrap())
+                i8::from_le_bytes(self.value.as_ref().try_into().unwrap())
             ),
             HeaderKind::Int16 => format!(
                 "{}",
-                i16::from_le_bytes(self.value.to_vec().try_into().unwrap())
+                i16::from_le_bytes(self.value.as_ref().try_into().unwrap())
             ),
             HeaderKind::Int32 => format!(
                 "{}",
-                i32::from_le_bytes(self.value.to_vec().try_into().unwrap())
+                i32::from_le_bytes(self.value.as_ref().try_into().unwrap())
             ),
             HeaderKind::Int64 => format!(
                 "{}",
-                i64::from_le_bytes(self.value.to_vec().try_into().unwrap())
+                i64::from_le_bytes(self.value.as_ref().try_into().unwrap())
             ),
             HeaderKind::Int128 => format!(
                 "{}",
-                i128::from_le_bytes(self.value.to_vec().try_into().unwrap())
+                i128::from_le_bytes(self.value.as_ref().try_into().unwrap())
             ),
             HeaderKind::Uint8 => format!(
                 "{}",
-                u8::from_le_bytes(self.value.to_vec().try_into().unwrap())
+                u8::from_le_bytes(self.value.as_ref().try_into().unwrap())
             ),
             HeaderKind::Uint16 => format!(
                 "{}",
-                u16::from_le_bytes(self.value.to_vec().try_into().unwrap())
+                u16::from_le_bytes(self.value.as_ref().try_into().unwrap())
             ),
             HeaderKind::Uint32 => format!(
                 "{}",
-                u32::from_le_bytes(self.value.to_vec().try_into().unwrap())
+                u32::from_le_bytes(self.value.as_ref().try_into().unwrap())
             ),
             HeaderKind::Uint64 => format!(
                 "{}",
-                u64::from_le_bytes(self.value.to_vec().try_into().unwrap())
+                u64::from_le_bytes(self.value.as_ref().try_into().unwrap())
             ),
             HeaderKind::Uint128 => format!(
                 "{}",
-                u128::from_le_bytes(self.value.to_vec().try_into().unwrap())
+                u128::from_le_bytes(self.value.as_ref().try_into().unwrap())
             ),
             HeaderKind::Float32 => format!(
                 "{}",
-                f32::from_le_bytes(self.value.to_vec().try_into().unwrap())
+                f32::from_le_bytes(self.value.as_ref().try_into().unwrap())
             ),
             HeaderKind::Float64 => format!(
                 "{}",
-                f64::from_le_bytes(self.value.to_vec().try_into().unwrap())
+                f64::from_le_bytes(self.value.as_ref().try_into().unwrap())
             ),
         }
     }
 
-    fn from(kind: HeaderKind, value: &[u8]) -> Result<Self, IggyError> {
-        if value.is_empty() || value.len() > 255 {
-            return Err(IggyError::InvalidHeaderValue);
-        }
-        Ok(Self {
+    fn new_unchecked(kind: HeaderKind, value: &[u8]) -> Self {
+        Self {
             kind,
             value: Bytes::from(value.to_vec()),
             _marker: PhantomData,
-        })
+        }
+    }
+}
+
+impl<T> TryFrom<&str> for HeaderField<T> {
+    type Error = IggyError;
+    fn try_from(value: &str) -> Result<Self, Self::Error> {
+        if value.is_empty() || value.len() > 255 {
+            return Err(IggyError::InvalidHeaderValue);
+        }
+        Ok(Self::new_unchecked(HeaderKind::String, value.as_bytes()))
+    }
+}
+
+impl<T> TryFrom<String> for HeaderField<T> {
+    type Error = IggyError;
+    fn try_from(value: String) -> Result<Self, Self::Error> {
+        Self::try_from(value.as_str())
+    }
+}
+
+impl<T> TryFrom<&[u8]> for HeaderField<T> {
+    type Error = IggyError;
+    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
+        if value.is_empty() || value.len() > 255 {
+            return Err(IggyError::InvalidHeaderValue);
+        }
+        Ok(Self::new_unchecked(HeaderKind::Raw, value))
+    }
+}
+
+impl<T> TryFrom<Vec<u8>> for HeaderField<T> {
+    type Error = IggyError;
+    fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
+        Self::try_from(value.as_slice())
+    }
+}
+
+impl<T> From<bool> for HeaderField<T> {
+    fn from(value: bool) -> Self {
+        Self::new_unchecked(HeaderKind::Bool, if value { &[1] } else { &[0] })
+    }
+}
+
+impl<T> From<i8> for HeaderField<T> {
+    fn from(value: i8) -> Self {
+        Self::new_unchecked(HeaderKind::Int8, &value.to_le_bytes())
+    }
+}
+
+impl<T> From<i16> for HeaderField<T> {
+    fn from(value: i16) -> Self {
+        Self::new_unchecked(HeaderKind::Int16, &value.to_le_bytes())
+    }
+}
+
+impl<T> From<i32> for HeaderField<T> {
+    fn from(value: i32) -> Self {
+        Self::new_unchecked(HeaderKind::Int32, &value.to_le_bytes())
+    }
+}
+
+impl<T> From<i64> for HeaderField<T> {
+    fn from(value: i64) -> Self {
+        Self::new_unchecked(HeaderKind::Int64, &value.to_le_bytes())
+    }
+}
+
+impl<T> From<i128> for HeaderField<T> {
+    fn from(value: i128) -> Self {
+        Self::new_unchecked(HeaderKind::Int128, &value.to_le_bytes())
+    }
+}
+
+impl<T> From<u8> for HeaderField<T> {
+    fn from(value: u8) -> Self {
+        Self::new_unchecked(HeaderKind::Uint8, &value.to_le_bytes())
+    }
+}
+
+impl<T> From<u16> for HeaderField<T> {
+    fn from(value: u16) -> Self {
+        Self::new_unchecked(HeaderKind::Uint16, &value.to_le_bytes())
+    }
+}
+
+impl<T> From<u32> for HeaderField<T> {
+    fn from(value: u32) -> Self {
+        Self::new_unchecked(HeaderKind::Uint32, &value.to_le_bytes())
+    }
+}
+
+impl<T> From<u64> for HeaderField<T> {
+    fn from(value: u64) -> Self {
+        Self::new_unchecked(HeaderKind::Uint64, &value.to_le_bytes())
+    }
+}
+
+impl<T> From<u128> for HeaderField<T> {
+    fn from(value: u128) -> Self {
+        Self::new_unchecked(HeaderKind::Uint128, &value.to_le_bytes())
+    }
+}
+
+impl<T> From<f32> for HeaderField<T> {
+    fn from(value: f32) -> Self {
+        Self::new_unchecked(HeaderKind::Float32, &value.to_le_bytes())
+    }
+}
+
+impl<T> From<f64> for HeaderField<T> {
+    fn from(value: f64) -> Self {
+        Self::new_unchecked(HeaderKind::Float64, &value.to_le_bytes())
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for bool {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_bool()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for bool {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_bool()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for i8 {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_int8()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for i8 {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_int8()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for i16 {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_int16()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for i16 {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_int16()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for i32 {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_int32()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for i32 {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_int32()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for i64 {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_int64()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for i64 {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_int64()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for i128 {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_int128()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for i128 {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_int128()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for u8 {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_uint8()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for u8 {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_uint8()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for u16 {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_uint16()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for u16 {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_uint16()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for u32 {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_uint32()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for u32 {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_uint32()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for u64 {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_uint64()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for u64 {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_uint64()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for u128 {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_uint128()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for u128 {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_uint128()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for f32 {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_float32()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for f32 {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_float32()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for f64 {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_float64()
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for f64 {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_float64()
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for String {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_str().map(|s| s.to_owned())
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for String {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_str().map(|s| s.to_owned())
+    }
+}
+
+impl<T> TryFrom<HeaderField<T>> for Vec<u8> {
+    type Error = IggyError;
+    fn try_from(field: HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_raw().map(|s| s.to_vec())
+    }
+}
+
+impl<T> TryFrom<&HeaderField<T>> for Vec<u8> {
+    type Error = IggyError;
+    fn try_from(field: &HeaderField<T>) -> Result<Self, Self::Error> {
+        field.as_raw().map(|s| s.to_vec())
     }
 }
 
@@ -659,7 +1006,7 @@ mod tests {
     #[test]
     fn header_key_should_be_created_for_valid_value() {
         let value = "key-1";
-        let header_key = HeaderKey::from_string(value);
+        let header_key = HeaderKey::try_from(value);
         assert!(header_key.is_ok());
         let header_key = header_key.unwrap();
         assert_eq!(header_key.kind, HeaderKind::String);
@@ -669,7 +1016,7 @@ mod tests {
     #[test]
     fn header_key_should_not_be_created_for_empty_value() {
         let value = "";
-        let header_key = HeaderKey::from_string(value);
+        let header_key = HeaderKey::try_from(value);
         assert!(header_key.is_err());
         let error = header_key.unwrap_err();
         assert_eq!(error.as_code(), IggyError::InvalidHeaderValue.as_code());
@@ -678,7 +1025,7 @@ mod tests {
     #[test]
     fn header_key_should_not_be_created_for_too_long_value() {
         let value = "a".repeat(256);
-        let header_key = HeaderKey::from_string(&value);
+        let header_key = HeaderKey::try_from(value.as_str());
         assert!(header_key.is_err());
         let error = header_key.unwrap_err();
         assert_eq!(error.as_code(), IggyError::InvalidHeaderValue.as_code());
@@ -687,16 +1034,14 @@ mod tests {
     #[test]
     fn header_key_should_be_created_from_int32() {
         let value = 12345i32;
-        let header_key = HeaderKey::from_int32(value);
-        assert!(header_key.is_ok());
-        let header_key = header_key.unwrap();
+        let header_key: HeaderKey = value.into();
         assert_eq!(header_key.kind, HeaderKind::Int32);
         assert_eq!(header_key.as_int32().unwrap(), value);
     }
 
     #[test]
     fn header_value_should_not_be_created_for_empty_value() {
-        let header_value = HeaderValue::from_raw(&[]);
+        let header_value = HeaderValue::try_from([].as_slice());
         assert!(header_value.is_err());
         let error = header_value.unwrap_err();
         assert_eq!(error.as_code(), IggyError::InvalidHeaderValue.as_code());
@@ -705,7 +1050,7 @@ mod tests {
     #[test]
     fn header_value_should_not_be_created_for_too_long_value() {
         let value = b"a".repeat(256);
-        let header_value = HeaderValue::from_raw(&value);
+        let header_value = HeaderValue::try_from(value.as_slice());
         assert!(header_value.is_err());
         let error = header_value.unwrap_err();
         assert_eq!(error.as_code(), IggyError::InvalidHeaderValue.as_code());
@@ -714,7 +1059,7 @@ mod tests {
     #[test]
     fn header_value_should_be_created_from_raw_bytes() {
         let value = b"Value 1";
-        let header_value = HeaderValue::from_raw(value);
+        let header_value = HeaderValue::try_from(value.as_slice());
         assert!(header_value.is_ok());
         assert_eq!(header_value.unwrap().value.as_ref(), value);
     }
@@ -733,9 +1078,7 @@ mod tests {
     #[test]
     fn header_value_should_be_created_from_bool() {
         let value = true;
-        let header_value = HeaderValue::from_bool(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Bool);
         assert_eq!(header_value.value.as_ref(), if value { [1] } else { [0] });
         assert_eq!(header_value.as_bool().unwrap(), value);
@@ -743,10 +1086,8 @@ mod tests {
 
     #[test]
     fn header_value_should_be_created_from_int8() {
-        let value = 123;
-        let header_value = HeaderValue::from_int8(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let value: i8 = 123;
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Int8);
         assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
         assert_eq!(header_value.as_int8().unwrap(), value);
@@ -754,10 +1095,8 @@ mod tests {
 
     #[test]
     fn header_value_should_be_created_from_int16() {
-        let value = 12345;
-        let header_value = HeaderValue::from_int16(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let value: i16 = 12345;
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Int16);
         assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
         assert_eq!(header_value.as_int16().unwrap(), value);
@@ -765,10 +1104,8 @@ mod tests {
 
     #[test]
     fn header_value_should_be_created_from_int32() {
-        let value = 123_456;
-        let header_value = HeaderValue::from_int32(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let value: i32 = 123_456;
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Int32);
         assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
         assert_eq!(header_value.as_int32().unwrap(), value);
@@ -776,10 +1113,8 @@ mod tests {
 
     #[test]
     fn header_value_should_be_created_from_int64() {
-        let value = 123_4567;
-        let header_value = HeaderValue::from_int64(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let value: i64 = 123_4567;
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Int64);
         assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
         assert_eq!(header_value.as_int64().unwrap(), value);
@@ -787,10 +1122,8 @@ mod tests {
 
     #[test]
     fn header_value_should_be_created_from_int128() {
-        let value = 1234_5678;
-        let header_value = HeaderValue::from_int128(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let value: i128 = 1234_5678;
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Int128);
         assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
         assert_eq!(header_value.as_int128().unwrap(), value);
@@ -798,10 +1131,8 @@ mod tests {
 
     #[test]
     fn header_value_should_be_created_from_uint8() {
-        let value = 123;
-        let header_value = HeaderValue::from_uint8(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let value: u8 = 123;
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Uint8);
         assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
         assert_eq!(header_value.as_uint8().unwrap(), value);
@@ -809,10 +1140,8 @@ mod tests {
 
     #[test]
     fn header_value_should_be_created_from_uint16() {
-        let value = 12345;
-        let header_value = HeaderValue::from_uint16(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let value: u16 = 12345;
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Uint16);
         assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
         assert_eq!(header_value.as_uint16().unwrap(), value);
@@ -820,10 +1149,8 @@ mod tests {
 
     #[test]
     fn header_value_should_be_created_from_uint32() {
-        let value = 123_456;
-        let header_value = HeaderValue::from_uint32(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let value: u32 = 123_456;
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Uint32);
         assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
         assert_eq!(header_value.as_uint32().unwrap(), value);
@@ -831,10 +1158,8 @@ mod tests {
 
     #[test]
     fn header_value_should_be_created_from_uint64() {
-        let value = 123_4567;
-        let header_value = HeaderValue::from_uint64(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let value: u64 = 123_4567;
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Uint64);
         assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
         assert_eq!(header_value.as_uint64().unwrap(), value);
@@ -842,10 +1167,8 @@ mod tests {
 
     #[test]
     fn header_value_should_be_created_from_uint128() {
-        let value = 1234_5678;
-        let header_value = HeaderValue::from_uint128(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let value: u128 = 1234_5678;
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Uint128);
         assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
         assert_eq!(header_value.as_uint128().unwrap(), value);
@@ -853,10 +1176,8 @@ mod tests {
 
     #[test]
     fn header_value_should_be_created_from_float32() {
-        let value = 123.01;
-        let header_value = HeaderValue::from_float32(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let value: f32 = 123.01;
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Float32);
         assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
         assert_eq!(header_value.as_float32().unwrap(), value);
@@ -864,250 +1185,13 @@ mod tests {
 
     #[test]
     fn header_value_should_be_created_from_float64() {
-        let value = 1234.01234;
-        let header_value = HeaderValue::from_float64(value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Float64);
-        assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
-        assert_eq!(header_value.as_float64().unwrap(), value);
-    }
-
-    #[test]
-    fn header_value_should_be_created_string_from_kind_and_value_str() {
-        let value = "Value 1";
-        let header_value = HeaderValue::from_kind_str_and_value_str("string", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::String);
-        assert_eq!(header_value.value, value.as_bytes());
-        assert_eq!(header_value.as_str().unwrap(), value);
-    }
-
-    #[test]
-    fn header_value_should_be_created_float_from_kind_and_value_str() {
         let value: f64 = 1234.01234;
-        let header_value = HeaderValue::from_kind_str_and_value_str("float64", 
&value.to_string());
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
+        let header_value: HeaderValue = value.into();
         assert_eq!(header_value.kind, HeaderKind::Float64);
         assert_eq!(header_value.value.as_ref(), value.to_le_bytes());
         assert_eq!(header_value.as_float64().unwrap(), value);
     }
 
-    #[test]
-    fn header_value_should_be_created_raw_from_kind_and_value_str() {
-        let value = "Value 1";
-        let header_value = HeaderValue::from_kind_str_and_value_str("raw", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Raw);
-        assert_eq!(header_value.value, value.as_bytes());
-    }
-
-    #[test]
-    fn header_value_should_be_created_bool_from_kind_and_value_str() {
-        let value = "true";
-        let header_value = HeaderValue::from_kind_str_and_value_str("bool", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Bool);
-        assert_eq!(header_value.value, vec![1]);
-        assert!(header_value.as_bool().unwrap());
-    }
-
-    #[test]
-    fn header_value_should_be_created_int8_from_kind_and_value_str() {
-        let value = "123";
-        let header_value = HeaderValue::from_kind_str_and_value_str("int8", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Int8);
-        assert_eq!(header_value.value, vec![123]);
-        assert_eq!(header_value.as_int8().unwrap(), 123);
-    }
-
-    #[test]
-    fn header_value_should_be_created_int16_from_kind_and_value_str() {
-        let value = "1234";
-        let header_value = HeaderValue::from_kind_str_and_value_str("int16", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Int16);
-        assert_eq!(
-            header_value.value.as_ref(),
-            value.parse::<i16>().unwrap().to_le_bytes()
-        );
-        assert_eq!(
-            header_value.as_int16().unwrap(),
-            value.parse::<i16>().unwrap()
-        );
-    }
-
-    #[test]
-    fn header_value_should_be_created_int32_from_kind_and_value_str() {
-        let value = "123456";
-        let header_value = HeaderValue::from_kind_str_and_value_str("int32", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Int32);
-        assert_eq!(
-            header_value.value.as_ref(),
-            value.parse::<i32>().unwrap().to_le_bytes()
-        );
-        assert_eq!(
-            header_value.as_int32().unwrap(),
-            value.parse::<i32>().unwrap()
-        );
-    }
-
-    #[test]
-    fn header_value_should_be_created_int64_from_kind_and_value_str() {
-        let value = "123456789";
-        let header_value = HeaderValue::from_kind_str_and_value_str("int64", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Int64);
-        assert_eq!(
-            header_value.value.as_ref(),
-            value.parse::<i64>().unwrap().to_le_bytes()
-        );
-        assert_eq!(
-            header_value.as_int64().unwrap(),
-            value.parse::<i64>().unwrap()
-        );
-    }
-
-    #[test]
-    fn header_value_should_be_created_int128_from_kind_and_value_str() {
-        let value = "123456789123456789";
-        let header_value = HeaderValue::from_kind_str_and_value_str("int128", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Int128);
-        assert_eq!(
-            header_value.value.as_ref(),
-            value.parse::<i128>().unwrap().to_le_bytes()
-        );
-        assert_eq!(
-            header_value.as_int128().unwrap(),
-            value.parse::<i128>().unwrap()
-        );
-    }
-
-    #[test]
-    fn header_value_should_be_created_uint8_from_kind_and_value_str() {
-        let value = "123";
-        let header_value = HeaderValue::from_kind_str_and_value_str("uint8", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Uint8);
-        assert_eq!(header_value.value, vec![123]);
-        assert_eq!(header_value.as_uint8().unwrap(), 123);
-    }
-
-    #[test]
-    fn header_value_should_be_created_uint16_from_kind_and_value_str() {
-        let value = "12345";
-        let header_value = HeaderValue::from_kind_str_and_value_str("uint16", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Uint16);
-        assert_eq!(
-            header_value.value.as_ref(),
-            value.parse::<u16>().unwrap().to_le_bytes()
-        );
-        assert_eq!(
-            header_value.as_uint16().unwrap(),
-            value.parse::<u16>().unwrap()
-        );
-    }
-
-    #[test]
-    fn header_value_should_be_created_uint32_from_kind_and_value_str() {
-        let value = "123456";
-        let header_value = HeaderValue::from_kind_str_and_value_str("uint32", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Uint32);
-        assert_eq!(
-            header_value.value.as_ref(),
-            value.parse::<u32>().unwrap().to_le_bytes()
-        );
-        assert_eq!(
-            header_value.as_uint32().unwrap(),
-            value.parse::<u32>().unwrap()
-        );
-    }
-
-    #[test]
-    fn header_value_should_be_created_uint64_from_kind_and_value_str() {
-        let value = "123456789";
-        let header_value = HeaderValue::from_kind_str_and_value_str("uint64", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Uint64);
-        assert_eq!(
-            header_value.value.as_ref(),
-            value.parse::<u64>().unwrap().to_le_bytes()
-        );
-        assert_eq!(
-            header_value.as_uint64().unwrap(),
-            value.parse::<u64>().unwrap()
-        );
-    }
-
-    #[test]
-    fn header_value_should_be_created_uint128_from_kind_and_value_str() {
-        let value = "123456789123456789";
-        let header_value = HeaderValue::from_kind_str_and_value_str("uint128", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Uint128);
-        assert_eq!(
-            header_value.value.as_ref(),
-            value.parse::<u128>().unwrap().to_le_bytes()
-        );
-        assert_eq!(
-            header_value.as_uint128().unwrap(),
-            value.parse::<u128>().unwrap()
-        );
-    }
-
-    #[test]
-    fn header_value_should_be_created_float32_from_kind_and_value_str() {
-        let value = "123.01";
-        let header_value = HeaderValue::from_kind_str_and_value_str("float32", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Float32);
-        assert_eq!(
-            header_value.value.as_ref(),
-            value.parse::<f32>().unwrap().to_le_bytes()
-        );
-        assert_eq!(
-            header_value.as_float32().unwrap(),
-            value.parse::<f32>().unwrap()
-        );
-    }
-
-    #[test]
-    fn header_value_should_be_created_float64_from_kind_and_value_str() {
-        let value = "1234.01234";
-        let header_value = HeaderValue::from_kind_str_and_value_str("float64", 
value);
-        assert!(header_value.is_ok());
-        let header_value = header_value.unwrap();
-        assert_eq!(header_value.kind, HeaderKind::Float64);
-        assert_eq!(
-            header_value.value.as_ref(),
-            value.parse::<f64>().unwrap().to_le_bytes()
-        );
-        assert_eq!(
-            header_value.as_float64().unwrap(),
-            value.parse::<f64>().unwrap()
-        );
-    }
-
     #[test]
     fn to_string_value_for_string_kind() {
         let header_value = HeaderValue::from_str("Hello").unwrap();
@@ -1116,79 +1200,79 @@ mod tests {
 
     #[test]
     fn to_string_value_for_bool_kind() {
-        let header_value = HeaderValue::from_bool(true).unwrap();
+        let header_value: HeaderValue = true.into();
         assert_eq!(header_value.to_string_value(), "true");
     }
 
     #[test]
     fn to_string_value_for_int8_kind() {
-        let header_value = HeaderValue::from_int8(123).unwrap();
+        let header_value: HeaderValue = 123i8.into();
         assert_eq!(header_value.to_string_value(), "123");
     }
 
     #[test]
     fn to_string_value_for_int16_kind() {
-        let header_value = HeaderValue::from_int16(12345).unwrap();
+        let header_value: HeaderValue = 12345i16.into();
         assert_eq!(header_value.to_string_value(), "12345");
     }
 
     #[test]
     fn to_string_value_for_int32_kind() {
-        let header_value = HeaderValue::from_int32(123456).unwrap();
+        let header_value: HeaderValue = 123456i32.into();
         assert_eq!(header_value.to_string_value(), "123456");
     }
 
     #[test]
     fn to_string_value_for_int64_kind() {
-        let header_value = HeaderValue::from_int64(123456789).unwrap();
+        let header_value: HeaderValue = 123456789i64.into();
         assert_eq!(header_value.to_string_value(), "123456789");
     }
 
     #[test]
     fn to_string_value_for_int128_kind() {
-        let header_value = 
HeaderValue::from_int128(123456789123456789).unwrap();
+        let header_value: HeaderValue = 123456789123456789i128.into();
         assert_eq!(header_value.to_string_value(), "123456789123456789");
     }
 
     #[test]
     fn to_string_value_for_uint8_kind() {
-        let header_value = HeaderValue::from_uint8(123).unwrap();
+        let header_value: HeaderValue = 123u8.into();
         assert_eq!(header_value.to_string_value(), "123");
     }
 
     #[test]
     fn to_string_value_for_uint16_kind() {
-        let header_value = HeaderValue::from_uint16(12345).unwrap();
+        let header_value: HeaderValue = 12345u16.into();
         assert_eq!(header_value.to_string_value(), "12345");
     }
 
     #[test]
     fn to_string_value_for_uint32_kind() {
-        let header_value = HeaderValue::from_uint32(123456).unwrap();
+        let header_value: HeaderValue = 123456u32.into();
         assert_eq!(header_value.to_string_value(), "123456");
     }
 
     #[test]
     fn to_string_value_for_uint64_kind() {
-        let header_value = HeaderValue::from_uint64(123456789).unwrap();
+        let header_value: HeaderValue = 123456789u64.into();
         assert_eq!(header_value.to_string_value(), "123456789");
     }
 
     #[test]
     fn to_string_value_for_uint128_kind() {
-        let header_value = 
HeaderValue::from_uint128(123456789123456789).unwrap();
+        let header_value: HeaderValue = 123456789123456789u128.into();
         assert_eq!(header_value.to_string_value(), "123456789123456789");
     }
 
     #[test]
     fn to_string_value_for_float32_kind() {
-        let header_value = HeaderValue::from_float32(123.01).unwrap();
+        let header_value: HeaderValue = 123.01f32.into();
         assert_eq!(header_value.to_string_value(), "123.01");
     }
 
     #[test]
     fn to_string_value_for_float64_kind() {
-        let header_value = HeaderValue::from_float64(1234.01234).unwrap();
+        let header_value: HeaderValue = 1234.01234f64.into();
         assert_eq!(header_value.to_string_value(), "1234.01234");
     }
 
@@ -1196,17 +1280,11 @@ mod tests {
     fn should_be_serialized_as_bytes() {
         let mut headers = HashMap::new();
         headers.insert(
-            HeaderKey::from_string("key-1").unwrap(),
+            HeaderKey::try_from("key-1").unwrap(),
             HeaderValue::from_str("Value 1").unwrap(),
         );
-        headers.insert(
-            HeaderKey::from_string("key 1").unwrap(),
-            HeaderValue::from_uint64(12345).unwrap(),
-        );
-        headers.insert(
-            HeaderKey::from_string("key_3").unwrap(),
-            HeaderValue::from_bool(true).unwrap(),
-        );
+        headers.insert(HeaderKey::try_from("key 1").unwrap(), 12345u64.into());
+        headers.insert(HeaderKey::try_from("key_3").unwrap(), true.into());
 
         let bytes = headers.to_bytes();
 
@@ -1249,17 +1327,11 @@ mod tests {
     fn should_be_deserialized_from_bytes() {
         let mut headers = HashMap::new();
         headers.insert(
-            HeaderKey::from_string("key-1").unwrap(),
+            HeaderKey::try_from("key-1").unwrap(),
             HeaderValue::from_str("Value 1").unwrap(),
         );
-        headers.insert(
-            HeaderKey::from_string("key 2").unwrap(),
-            HeaderValue::from_uint64(12345).unwrap(),
-        );
-        headers.insert(
-            HeaderKey::from_string("key_3").unwrap(),
-            HeaderValue::from_bool(true).unwrap(),
-        );
+        headers.insert(HeaderKey::try_from("key 2").unwrap(), 12345u64.into());
+        headers.insert(HeaderKey::try_from("key_3").unwrap(), true.into());
 
         let mut bytes = BytesMut::new();
         for (key, value) in &headers {
@@ -1290,13 +1362,10 @@ mod tests {
     fn should_serialize_and_deserialize_typed_keys() {
         let mut headers = HashMap::new();
         headers.insert(
-            HeaderKey::from_int32(123).unwrap(),
+            123i32.into(),
             HeaderValue::from_str("Value for int key").unwrap(),
         );
-        headers.insert(
-            HeaderKey::from_uint64(999).unwrap(),
-            HeaderValue::from_bool(true).unwrap(),
-        );
+        headers.insert(999u64.into(), true.into());
 
         let bytes = headers.to_bytes();
         let deserialized = HashMap::<HeaderKey, 
HeaderValue>::from_bytes(bytes).unwrap();
@@ -1310,4 +1379,164 @@ mod tests {
             assert_eq!(deserialized_value.value, value.value);
         }
     }
+
+    #[test]
+    fn header_value_should_be_created_from_vec_u8() {
+        let value = vec![1u8, 2, 3, 4, 5];
+        let header_value = HeaderValue::try_from(value.clone());
+        assert!(header_value.is_ok());
+        let header_value = header_value.unwrap();
+        assert_eq!(header_value.kind, HeaderKind::Raw);
+        assert_eq!(header_value.value.as_ref(), value.as_slice());
+        assert_eq!(header_value.as_raw().unwrap(), value.as_slice());
+    }
+
+    #[test]
+    fn header_value_should_not_be_created_from_empty_vec_u8() {
+        let value: Vec<u8> = vec![];
+        let header_value = HeaderValue::try_from(value);
+        assert!(header_value.is_err());
+        let error = header_value.unwrap_err();
+        assert_eq!(error.as_code(), IggyError::InvalidHeaderValue.as_code());
+    }
+
+    #[test]
+    fn header_value_should_not_be_created_from_too_long_vec_u8() {
+        let value: Vec<u8> = vec![0u8; 256];
+        let header_value = HeaderValue::try_from(value);
+        assert!(header_value.is_err());
+        let error = header_value.unwrap_err();
+        assert_eq!(error.as_code(), IggyError::InvalidHeaderValue.as_code());
+    }
+
+    #[test]
+    fn header_key_should_be_created_from_vec_u8() {
+        let value = vec![1u8, 2, 3, 4];
+        let header_key = HeaderKey::try_from(value.clone());
+        assert!(header_key.is_ok());
+        let header_key = header_key.unwrap();
+        assert_eq!(header_key.kind, HeaderKind::Raw);
+        assert_eq!(header_key.value.as_ref(), value.as_slice());
+    }
+
+    #[test]
+    fn header_value_should_convert_to_bool() {
+        let header_value: HeaderValue = true.into();
+        let extracted: bool = header_value.try_into().unwrap();
+        assert!(extracted);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_i8() {
+        let header_value: HeaderValue = 42i8.into();
+        let extracted: i8 = header_value.try_into().unwrap();
+        assert_eq!(extracted, 42);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_i16() {
+        let header_value: HeaderValue = 1234i16.into();
+        let extracted: i16 = header_value.try_into().unwrap();
+        assert_eq!(extracted, 1234);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_i32() {
+        let header_value: HeaderValue = 123456i32.into();
+        let extracted: i32 = header_value.try_into().unwrap();
+        assert_eq!(extracted, 123456);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_i64() {
+        let header_value: HeaderValue = 123456789i64.into();
+        let extracted: i64 = header_value.try_into().unwrap();
+        assert_eq!(extracted, 123456789);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_i128() {
+        let header_value: HeaderValue = 123456789123456789i128.into();
+        let extracted: i128 = header_value.try_into().unwrap();
+        assert_eq!(extracted, 123456789123456789);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_u8() {
+        let header_value: HeaderValue = 42u8.into();
+        let extracted: u8 = header_value.try_into().unwrap();
+        assert_eq!(extracted, 42);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_u16() {
+        let header_value: HeaderValue = 1234u16.into();
+        let extracted: u16 = header_value.try_into().unwrap();
+        assert_eq!(extracted, 1234);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_u32() {
+        let header_value: HeaderValue = 123456u32.into();
+        let extracted: u32 = header_value.try_into().unwrap();
+        assert_eq!(extracted, 123456);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_u64() {
+        let header_value: HeaderValue = 123456789u64.into();
+        let extracted: u64 = header_value.try_into().unwrap();
+        assert_eq!(extracted, 123456789);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_u128() {
+        let header_value: HeaderValue = 123456789123456789u128.into();
+        let extracted: u128 = header_value.try_into().unwrap();
+        assert_eq!(extracted, 123456789123456789);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_f32() {
+        let header_value: HeaderValue = 123.5f32.into();
+        let extracted: f32 = header_value.try_into().unwrap();
+        assert_eq!(extracted, 123.5);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_f64() {
+        let header_value: HeaderValue = 1234.5678f64.into();
+        let extracted: f64 = header_value.try_into().unwrap();
+        assert_eq!(extracted, 1234.5678);
+    }
+
+    #[test]
+    fn header_value_should_convert_to_string() {
+        let header_value = HeaderValue::try_from("hello").unwrap();
+        let extracted: String = header_value.try_into().unwrap();
+        assert_eq!(extracted, "hello");
+    }
+
+    #[test]
+    fn header_value_should_convert_to_vec_u8() {
+        let header_value = HeaderValue::try_from(vec![1u8, 2, 3]).unwrap();
+        let extracted: Vec<u8> = header_value.try_into().unwrap();
+        assert_eq!(extracted, vec![1u8, 2, 3]);
+    }
+
+    #[test]
+    fn header_value_should_fail_conversion_with_wrong_kind() {
+        let header_value: HeaderValue = 42i32.into();
+        let result: Result<u64, _> = header_value.try_into();
+        assert!(result.is_err());
+    }
+
+    #[test]
+    fn header_value_ref_should_convert_to_i32() {
+        let value = 123456i32;
+        let header_value: HeaderValue = value.into();
+        let extracted: i32 = (&header_value).try_into().unwrap();
+        assert_eq!(extracted, value);
+        assert_eq!(header_value.as_int32().unwrap(), value);
+    }
 }
diff --git a/core/integration/tests/cli/message/test_message_poll_command.rs 
b/core/integration/tests/cli/message/test_message_poll_command.rs
index 69f52e336..867a8aca1 100644
--- a/core/integration/tests/cli/message/test_message_poll_command.rs
+++ b/core/integration/tests/cli/message/test_message_poll_command.rs
@@ -195,7 +195,10 @@ impl IggyCmdTestCase for TestMessagePollCmd {
 
         if self.show_headers {
             status = status
-                .stdout(contains(format!("Header: {}", self.headers.0)))
+                .stdout(contains(format!(
+                    "Header: {}",
+                    self.headers.0.to_string_value()
+                )))
                 .stdout(contains(self.headers.1.kind.to_string()))
                 
.stdout(contains(self.headers.1.to_string_value()).count(self.message_count))
         }
diff --git a/core/integration/tests/cli/message/test_message_send_command.rs 
b/core/integration/tests/cli/message/test_message_send_command.rs
index b0dcb27b6..fea3498e5 100644
--- a/core/integration/tests/cli/message/test_message_send_command.rs
+++ b/core/integration/tests/cli/message/test_message_send_command.rs
@@ -109,7 +109,9 @@ impl TestMessageSendCmd {
             command.push(
                 header
                     .iter()
-                    .map(|(k, v)| format!("{k}:{}:{}", v.kind, 
v.to_string_value()))
+                    .map(|(k, v)| {
+                        format!("{}:{}:{}", k.to_string_value(), v.kind, 
v.to_string_value())
+                    })
                     .collect::<Vec<_>>()
                     .join(","),
             );
@@ -340,13 +342,10 @@ pub async fn should_be_successful() {
                 using_partitioning,
                 Some(HashMap::from([
                     (
-                        HeaderKey::from_string("key1").unwrap(),
-                        HeaderValue::from_kind_str_and_value_str("string", 
"value1").unwrap(),
-                    ),
-                    (
-                        HeaderKey::from_string("key2").unwrap(),
-                        HeaderValue::from_kind_str_and_value_str("int32", 
"42").unwrap(),
+                        HeaderKey::try_from("key1").unwrap(),
+                        HeaderValue::try_from("value1").unwrap(),
                     ),
+                    (HeaderKey::try_from("key2").unwrap(), 42i32.into()),
                 ])),
             ))
             .await;
diff --git a/core/integration/tests/server/scenarios/create_message_payload.rs 
b/core/integration/tests/server/scenarios/create_message_payload.rs
index 20d1127af..1add0b0f7 100644
--- a/core/integration/tests/server/scenarios/create_message_payload.rs
+++ b/core/integration/tests/server/scenarios/create_message_payload.rs
@@ -20,7 +20,6 @@ use bytes::Bytes;
 use iggy::prelude::*;
 use integration::test_server::{ClientFactory, assert_clean_system, login_root};
 use std::collections::HashMap;
-use std::str::FromStr;
 
 const STREAM_NAME: &str = "test-stream";
 const TOPIC_NAME: &str = "test-topic";
@@ -82,7 +81,7 @@ pub async fn run(client_factory: &dyn ClientFactory) {
         assert_eq!(headers.len(), 3);
         assert_eq!(
             headers
-                .get(&HeaderKey::from_string("key_1").unwrap())
+                .get(&HeaderKey::try_from("key_1").unwrap())
                 .unwrap()
                 .as_str()
                 .unwrap(),
@@ -90,14 +89,14 @@ pub async fn run(client_factory: &dyn ClientFactory) {
         );
         assert!(
             headers
-                .get(&HeaderKey::from_string("key 2").unwrap())
+                .get(&HeaderKey::try_from("key 2").unwrap())
                 .unwrap()
                 .as_bool()
                 .unwrap(),
         );
         assert_eq!(
             headers
-                .get(&HeaderKey::from_string("key-3").unwrap())
+                .get(&HeaderKey::try_from("key-3").unwrap())
                 .unwrap()
                 .as_uint64()
                 .unwrap(),
@@ -141,16 +140,10 @@ fn create_message_payload(offset: u64) -> Bytes {
 fn create_message_headers() -> HashMap<HeaderKey, HeaderValue> {
     let mut headers = HashMap::new();
     headers.insert(
-        HeaderKey::from_string("key_1").unwrap(),
-        HeaderValue::from_str("Value 1").unwrap(),
-    );
-    headers.insert(
-        HeaderKey::from_string("key 2").unwrap(),
-        HeaderValue::from_bool(true).unwrap(),
-    );
-    headers.insert(
-        HeaderKey::from_string("key-3").unwrap(),
-        HeaderValue::from_uint64(123456).unwrap(),
+        HeaderKey::try_from("key_1").unwrap(),
+        HeaderValue::try_from("Value 1").unwrap(),
     );
+    headers.insert(HeaderKey::try_from("key 2").unwrap(), true.into());
+    headers.insert(HeaderKey::try_from("key-3").unwrap(), 123456u64.into());
     headers
 }
diff --git a/core/integration/tests/server/scenarios/encryption_scenario.rs 
b/core/integration/tests/server/scenarios/encryption_scenario.rs
index 23dd5c19c..49f608173 100644
--- a/core/integration/tests/server/scenarios/encryption_scenario.rs
+++ b/core/integration/tests/server/scenarios/encryption_scenario.rs
@@ -23,7 +23,7 @@ use integration::{
     test_server::{ClientFactory, IpAddrKind, SYSTEM_PATH_ENV_VAR, TestServer, 
login_root},
 };
 use serial_test::parallel;
-use std::{collections::HashMap, str::FromStr};
+use std::collections::HashMap;
 use test_case::test_matrix;
 
 fn encryption_enabled() -> bool {
@@ -97,22 +97,13 @@ async fn 
should_fill_data_with_headers_and_verify_after_restart_using_api(encryp
 
     for i in 0..messages_per_batch {
         let mut headers = HashMap::new();
+        headers.insert(HeaderKey::try_from("batch").unwrap(), 1u64.into());
+        headers.insert(HeaderKey::try_from("index").unwrap(), i.into());
         headers.insert(
-            HeaderKey::from_string("batch").unwrap(),
-            HeaderValue::from_uint64(1).unwrap(),
-        );
-        headers.insert(
-            HeaderKey::from_string("index").unwrap(),
-            HeaderValue::from_uint64(i).unwrap(),
-        );
-        headers.insert(
-            HeaderKey::from_string("type").unwrap(),
-            HeaderValue::from_str("test-message").unwrap(),
-        );
-        headers.insert(
-            HeaderKey::from_string("encrypted").unwrap(),
-            HeaderValue::from_bool(encryption).unwrap(),
+            HeaderKey::try_from("type").unwrap(),
+            HeaderValue::try_from("test-message").unwrap(),
         );
+        headers.insert(HeaderKey::try_from("encrypted").unwrap(), 
encryption.into());
 
         let message = IggyMessage::builder()
             .id((i + 1) as u128)
@@ -195,7 +186,7 @@ async fn 
should_fill_data_with_headers_and_verify_after_restart_using_api(encryp
         let headers = msg.user_headers_map().unwrap().unwrap();
         assert_eq!(
             headers
-                .get(&HeaderKey::from_string("batch").unwrap())
+                .get(&HeaderKey::try_from("batch").unwrap())
                 .unwrap()
                 .as_uint64()
                 .unwrap(),
@@ -203,7 +194,7 @@ async fn 
should_fill_data_with_headers_and_verify_after_restart_using_api(encryp
         );
         assert_eq!(
             headers
-                .get(&HeaderKey::from_string("type").unwrap())
+                .get(&HeaderKey::try_from("type").unwrap())
                 .unwrap()
                 .as_str()
                 .unwrap(),
@@ -211,7 +202,7 @@ async fn 
should_fill_data_with_headers_and_verify_after_restart_using_api(encryp
         );
         assert_eq!(
             headers
-                .get(&HeaderKey::from_string("encrypted").unwrap())
+                .get(&HeaderKey::try_from("encrypted").unwrap())
                 .unwrap()
                 .as_bool()
                 .unwrap(),
@@ -242,22 +233,13 @@ async fn 
should_fill_data_with_headers_and_verify_after_restart_using_api(encryp
 
     for i in 0..messages_per_batch {
         let mut headers = HashMap::new();
+        headers.insert(HeaderKey::try_from("batch").unwrap(), 2u64.into());
+        headers.insert(HeaderKey::try_from("index").unwrap(), i.into());
         headers.insert(
-            HeaderKey::from_string("batch").unwrap(),
-            HeaderValue::from_uint64(2).unwrap(),
-        );
-        headers.insert(
-            HeaderKey::from_string("index").unwrap(),
-            HeaderValue::from_uint64(i).unwrap(),
-        );
-        headers.insert(
-            HeaderKey::from_string("type").unwrap(),
-            HeaderValue::from_str("test-message-after-restart").unwrap(),
-        );
-        headers.insert(
-            HeaderKey::from_string("encrypted").unwrap(),
-            HeaderValue::from_bool(encryption).unwrap(),
+            HeaderKey::try_from("type").unwrap(),
+            HeaderValue::try_from("test-message-after-restart").unwrap(),
         );
+        headers.insert(HeaderKey::try_from("encrypted").unwrap(), 
encryption.into());
 
         let message = IggyMessage::builder()
             .id((messages_per_batch + i + 1) as u128)
@@ -322,7 +304,7 @@ async fn 
should_fill_data_with_headers_and_verify_after_restart_using_api(encryp
         assert!(msg.user_headers.is_some());
         let headers = msg.user_headers_map().unwrap().unwrap();
         let batch_num = headers
-            .get(&HeaderKey::from_string("batch").unwrap())
+            .get(&HeaderKey::try_from("batch").unwrap())
             .unwrap()
             .as_uint64()
             .unwrap();
@@ -331,7 +313,7 @@ async fn 
should_fill_data_with_headers_and_verify_after_restart_using_api(encryp
             batch_1_count += 1;
             assert_eq!(
                 headers
-                    .get(&HeaderKey::from_string("type").unwrap())
+                    .get(&HeaderKey::try_from("type").unwrap())
                     .unwrap()
                     .as_str()
                     .unwrap(),
@@ -339,7 +321,7 @@ async fn 
should_fill_data_with_headers_and_verify_after_restart_using_api(encryp
             );
             assert_eq!(
                 headers
-                    .get(&HeaderKey::from_string("encrypted").unwrap())
+                    .get(&HeaderKey::try_from("encrypted").unwrap())
                     .unwrap()
                     .as_bool()
                     .unwrap(),
@@ -349,7 +331,7 @@ async fn 
should_fill_data_with_headers_and_verify_after_restart_using_api(encryp
             batch_2_count += 1;
             assert_eq!(
                 headers
-                    .get(&HeaderKey::from_string("type").unwrap())
+                    .get(&HeaderKey::try_from("type").unwrap())
                     .unwrap()
                     .as_str()
                     .unwrap(),
diff --git 
a/core/integration/tests/server/scenarios/message_headers_scenario.rs 
b/core/integration/tests/server/scenarios/message_headers_scenario.rs
index 4de9afb29..1d8b1e190 100644
--- a/core/integration/tests/server/scenarios/message_headers_scenario.rs
+++ b/core/integration/tests/server/scenarios/message_headers_scenario.rs
@@ -23,7 +23,6 @@ use bytes::Bytes;
 use iggy::prelude::*;
 use integration::test_server::{ClientFactory, assert_clean_system, login_root};
 use std::collections::HashMap;
-use std::str::FromStr;
 
 pub async fn run(client_factory: &dyn ClientFactory) {
     let client = create_client(client_factory).await;
@@ -79,7 +78,7 @@ pub async fn run(client_factory: &dyn ClientFactory) {
         assert_eq!(headers.len(), 3);
         assert_eq!(
             headers
-                .get(&HeaderKey::from_string("key_1").unwrap())
+                .get(&HeaderKey::try_from("key_1").unwrap())
                 .unwrap()
                 .as_str()
                 .unwrap(),
@@ -87,14 +86,14 @@ pub async fn run(client_factory: &dyn ClientFactory) {
         );
         assert!(
             headers
-                .get(&HeaderKey::from_string("key 2").unwrap())
+                .get(&HeaderKey::try_from("key 2").unwrap())
                 .unwrap()
                 .as_bool()
                 .unwrap(),
         );
         assert_eq!(
             headers
-                .get(&HeaderKey::from_string("key-3").unwrap())
+                .get(&HeaderKey::try_from("key-3").unwrap())
                 .unwrap()
                 .as_uint64()
                 .unwrap(),
@@ -131,16 +130,10 @@ fn create_message_payload(offset: u64) -> Bytes {
 fn create_message_headers() -> HashMap<HeaderKey, HeaderValue> {
     let mut headers = HashMap::new();
     headers.insert(
-        HeaderKey::from_string("key_1").unwrap(),
-        HeaderValue::from_str("Value 1").unwrap(),
-    );
-    headers.insert(
-        HeaderKey::from_string("key 2").unwrap(),
-        HeaderValue::from_bool(true).unwrap(),
-    );
-    headers.insert(
-        HeaderKey::from_string("key-3").unwrap(),
-        HeaderValue::from_uint64(123456).unwrap(),
+        HeaderKey::try_from("key_1").unwrap(),
+        HeaderValue::try_from("Value 1").unwrap(),
     );
+    headers.insert(HeaderKey::try_from("key 2").unwrap(), true.into());
+    headers.insert(HeaderKey::try_from("key-3").unwrap(), 123456u64.into());
     headers
 }
diff --git a/core/integration/tests/server/scenarios/message_size_scenario.rs 
b/core/integration/tests/server/scenarios/message_size_scenario.rs
index 04f831b18..f63b0570b 100644
--- a/core/integration/tests/server/scenarios/message_size_scenario.rs
+++ b/core/integration/tests/server/scenarios/message_size_scenario.rs
@@ -20,7 +20,6 @@ use bytes::Bytes;
 use iggy::prelude::*;
 use integration::test_server::{ClientFactory, assert_clean_system, login_root};
 use std::collections::HashMap;
-use std::str::FromStr;
 
 const STREAM_NAME: &str = "test-stream";
 const TOPIC_NAME: &str = "test-topic";
@@ -222,8 +221,8 @@ fn create_message_header_of_size(target_size: usize) -> 
HashMap<HeaderKey, Heade
             remaining_size - header_overhead
         };
 
-        let key = HeaderKey::from_raw(&key_bytes).unwrap();
-        let value = 
HeaderValue::from_str(create_string_of_size(value_size).as_str()).unwrap();
+        let key = HeaderKey::try_from(key_bytes.as_slice()).unwrap();
+        let value = 
HeaderValue::try_from(create_string_of_size(value_size).as_str()).unwrap();
 
         let actual_header_size = header_overhead + value_size;
         current_size += actual_header_size;
diff --git a/core/integration/tests/server/scenarios/offset_scenario.rs 
b/core/integration/tests/server/scenarios/offset_scenario.rs
index dd35892c8..608b1b3fb 100644
--- a/core/integration/tests/server/scenarios/offset_scenario.rs
+++ b/core/integration/tests/server/scenarios/offset_scenario.rs
@@ -21,7 +21,6 @@ use bytes::BytesMut;
 use iggy::prelude::*;
 use integration::test_server::{ClientFactory, login_root};
 use std::collections::HashMap;
-use std::str::FromStr;
 
 fn small_batches() -> Vec<u32> {
     vec![3, 4, 5, 6, 7]
@@ -174,17 +173,11 @@ fn create_single_message(id: u32, message_size: u64) -> 
IggyMessage {
 
     let mut headers = HashMap::new();
     headers.insert(
-        HeaderKey::from_string("key_1").unwrap(),
-        HeaderValue::from_str("Value 1").unwrap(),
-    );
-    headers.insert(
-        HeaderKey::from_string("key 2").unwrap(),
-        HeaderValue::from_bool(true).unwrap(),
-    );
-    headers.insert(
-        HeaderKey::from_string("key-3").unwrap(),
-        HeaderValue::from_uint64(123456).unwrap(),
+        HeaderKey::try_from("key_1").unwrap(),
+        HeaderValue::try_from("Value 1").unwrap(),
     );
+    headers.insert(HeaderKey::try_from("key 2").unwrap(), true.into());
+    headers.insert(HeaderKey::try_from("key-3").unwrap(), 123456u64.into());
 
     IggyMessage::builder()
         .id(id as u128)
diff --git a/core/integration/tests/server/scenarios/timestamp_scenario.rs 
b/core/integration/tests/server/scenarios/timestamp_scenario.rs
index d8ddfe109..eb5129701 100644
--- a/core/integration/tests/server/scenarios/timestamp_scenario.rs
+++ b/core/integration/tests/server/scenarios/timestamp_scenario.rs
@@ -21,7 +21,6 @@ use bytes::BytesMut;
 use iggy::prelude::*;
 use integration::test_server::{ClientFactory, login_root};
 use std::collections::HashMap;
-use std::str::FromStr;
 use tokio::time::{Duration, sleep};
 
 fn small_batches() -> Vec<u32> {
@@ -198,17 +197,11 @@ fn create_single_message(id: u32, message_size: u64) -> 
IggyMessage {
 
     let mut headers = HashMap::new();
     headers.insert(
-        HeaderKey::from_string("key_1").unwrap(),
-        HeaderValue::from_str("Value 1").unwrap(),
-    );
-    headers.insert(
-        HeaderKey::from_string("key 2").unwrap(),
-        HeaderValue::from_bool(true).unwrap(),
-    );
-    headers.insert(
-        HeaderKey::from_string("key-3").unwrap(),
-        HeaderValue::from_uint64(123456).unwrap(),
+        HeaderKey::try_from("key_1").unwrap(),
+        HeaderValue::try_from("Value 1").unwrap(),
     );
+    headers.insert(HeaderKey::try_from("key 2").unwrap(), true.into());
+    headers.insert(HeaderKey::try_from("key-3").unwrap(), 123456u64.into());
 
     IggyMessage::builder()
         .id(id as u128)
diff --git a/core/sdk/src/prelude.rs b/core/sdk/src/prelude.rs
index ba374fe6b..bcbb44f82 100644
--- a/core/sdk/src/prelude.rs
+++ b/core/sdk/src/prelude.rs
@@ -57,12 +57,12 @@ pub use iggy_common::{
     Aes256GcmEncryptor, Args, ArgsOptional, AutoLogin, BytesSerializable, 
CacheMetrics,
     CacheMetricsKey, ClientError, ClientInfoDetails, ClusterMetadata, 
ClusterNode, ClusterNodeRole,
     ClusterNodeStatus, CompressionAlgorithm, Consumer, ConsumerGroupDetails, 
ConsumerKind,
-    EncryptorKind, FlushUnsavedBuffer, GlobalPermissions, HeaderKey, 
HeaderValue, HttpClientConfig,
-    HttpClientConfigBuilder, IdKind, Identifier, IdentityInfo, IggyByteSize, 
IggyDuration,
-    IggyError, IggyExpiry, IggyIndexView, IggyMessage, IggyMessageHeader, 
IggyMessageHeaderView,
-    IggyMessageView, IggyMessageViewIterator, IggyTimestamp, MaxTopicSize, 
Partition, Partitioner,
-    Partitioning, Permissions, PersonalAccessTokenExpiry, PollMessages, 
PolledMessages,
-    PollingKind, PollingStrategy, QuicClientConfig, QuicClientConfigBuilder,
+    EncryptorKind, FlushUnsavedBuffer, GlobalPermissions, HeaderKey, 
HeaderKind, HeaderValue,
+    HttpClientConfig, HttpClientConfigBuilder, IdKind, Identifier, 
IdentityInfo, IggyByteSize,
+    IggyDuration, IggyError, IggyExpiry, IggyIndexView, IggyMessage, 
IggyMessageHeader,
+    IggyMessageHeaderView, IggyMessageView, IggyMessageViewIterator, 
IggyTimestamp, MaxTopicSize,
+    Partition, Partitioner, Partitioning, Permissions, 
PersonalAccessTokenExpiry, PollMessages,
+    PolledMessages, PollingKind, PollingStrategy, QuicClientConfig, 
QuicClientConfigBuilder,
     QuicClientReconnectionConfig, SendMessages, Sizeable, SnapshotCompression, 
Stats, Stream,
     StreamDetails, StreamPermissions, SystemSnapshotType, TcpClientConfig, 
TcpClientConfigBuilder,
     TcpClientReconnectionConfig, Topic, TopicDetails, TopicPermissions, 
TransportEndpoints,
diff --git a/core/server/server.http b/core/server/server.http
index 02a7d2d13..a2dbabf9c 100644
--- a/core/server/server.http
+++ b/core/server/server.http
@@ -25,7 +25,10 @@
 @partition_id_payload_base64 = AAAAAA==
 @message_1_payload_base64 = aGVsbG8=
 @message_2_payload_base64 = d29ybGQ=
-@header_1_payload_base_64 = dmFsdWUgMQ==
+@header_key_1_base64 = a2V5XzE=
+@header_value_1_base64 = dmFsdWUgMQ==
+@header_key_2_base64 = Kg==
+@header_value_2_base64 = AAAA
 @root_username = iggy
 @root_password = iggy
 @user1_username = user1
@@ -301,12 +304,25 @@ Content-Type: application/json
   }, {
     "id": 0,
     "payload": "{{message_2_payload_base64}}",
-    "headers": {
-      "key_1": {
+    "user_headers": [{
+      "key": {
         "kind": "string",
-        "value": "{{header_1_payload_base_64}}"
+        "value": "{{header_key_1_base64}}"
+      },
+      "value": {
+        "kind": "string",
+        "value": "{{header_value_1_base64}}"
       }
-    }
+    }, {
+      "key": {
+        "kind": "uint32",
+        "value": "{{header_key_2_base64}}"
+      },
+      "value": {
+        "kind": "int32",
+        "value": "{{header_value_2_base64}}"
+      }
+    }]
   }]
 }
 
diff --git a/core/tools/src/data-seeder/seeder.rs 
b/core/tools/src/data-seeder/seeder.rs
index 045cd3ffc..edbac98dc 100644
--- a/core/tools/src/data-seeder/seeder.rs
+++ b/core/tools/src/data-seeder/seeder.rs
@@ -19,7 +19,6 @@
 use iggy::prelude::*;
 use rand::Rng;
 use std::collections::HashMap;
-use std::str::FromStr;
 
 const PROD_STREAM_NAME: &str = "prod";
 const TEST_STREAM_NAME: &str = "test";
@@ -158,17 +157,11 @@ async fn send_messages(client: &IggyClient, streams: 
&[(String, u32)]) -> Result
                         true => {
                             let mut headers = HashMap::new();
                             headers.insert(
-                                HeaderKey::from_string("key 1")?,
-                                HeaderValue::from_str("value1")?,
-                            );
-                            headers.insert(
-                                HeaderKey::from_string("key-2")?,
-                                HeaderValue::from_bool(true)?,
-                            );
-                            headers.insert(
-                                HeaderKey::from_string("key_3")?,
-                                HeaderValue::from_uint64(123456)?,
+                                HeaderKey::try_from("key 1")?,
+                                HeaderValue::try_from("value1")?,
                             );
+                            headers.insert(HeaderKey::try_from("key-2")?, 
true.into());
+                            headers.insert(HeaderKey::try_from("key_3")?, 
123456u64.into());
                             Some(headers)
                         }
                     };
diff --git a/examples/rust/src/message-headers/message-type/consumer/main.rs 
b/examples/rust/src/message-headers/message-type/consumer/main.rs
index bdc6bb451..8ac62ffbf 100644
--- a/examples/rust/src/message-headers/message-type/consumer/main.rs
+++ b/examples/rust/src/message-headers/message-type/consumer/main.rs
@@ -51,7 +51,7 @@ fn handle_message(message: &IggyMessage) -> Result<(), 
Box<dyn Error>> {
     // The payload can be of any type as it is a raw byte array. In this case 
it's a JSON string.
     let payload = std::str::from_utf8(&message.payload)?;
     // The message type is stored in the custom message header.
-    let header_key = HeaderKey::from_string("message_type").unwrap();
+    let header_key = HeaderKey::try_from("message_type").unwrap();
     let headers_map = message.user_headers_map()?.unwrap();
     let message_type = headers_map.get(&header_key).unwrap().as_str()?;
     info!(
diff --git a/examples/rust/src/message-headers/message-type/producer/main.rs 
b/examples/rust/src/message-headers/message-type/producer/main.rs
index 680b56bd4..f394fddfe 100644
--- a/examples/rust/src/message-headers/message-type/producer/main.rs
+++ b/examples/rust/src/message-headers/message-type/producer/main.rs
@@ -24,7 +24,6 @@ use 
iggy_examples::shared::messages_generator::MessagesGenerator;
 use iggy_examples::shared::system;
 use std::collections::HashMap;
 use std::error::Error;
-use std::str::FromStr;
 use std::sync::Arc;
 use tracing::info;
 use tracing_subscriber::layer::SubscriberExt;
@@ -86,8 +85,8 @@ async fn produce_messages(args: &Args, client: &IggyClient) 
-> Result<(), Box<dy
             // The message type will be stored in the custom message header.
             let mut headers = HashMap::new();
             headers.insert(
-                HeaderKey::from_string("message_type").unwrap(),
-                HeaderValue::from_str(message_type).unwrap(),
+                HeaderKey::try_from("message_type").unwrap(),
+                HeaderValue::try_from(message_type).unwrap(),
             );
 
             let message = IggyMessage::builder()
diff --git a/examples/rust/src/message-headers/typed-headers/producer/main.rs 
b/examples/rust/src/message-headers/typed-headers/producer/main.rs
index 60d86687a..3e6d3c5a8 100644
--- a/examples/rust/src/message-headers/typed-headers/producer/main.rs
+++ b/examples/rust/src/message-headers/typed-headers/producer/main.rs
@@ -80,28 +80,22 @@ async fn produce_messages(args: &Args, client: &IggyClient) 
-> Result<(), Box<dy
 
             let mut headers = HashMap::new();
             headers.insert(
-                HeaderKey::from_string("event_type")?,
-                HeaderValue::from_string("user_action")?,
+                HeaderKey::try_from("event_type")?,
+                HeaderValue::try_from("user_action")?,
             );
+            headers.insert(1u32.into(), message_id.into());
             headers.insert(
-                HeaderKey::from_uint32(1)?,
-                HeaderValue::from_uint64(message_id)?,
+                HeaderKey::try_from("important")?,
+                message_id.is_multiple_of(5).into(),
             );
+            headers.insert(44u32.into(), (message_id as f64 * 2.0).into());
             headers.insert(
-                HeaderKey::from_string("important")?,
-                HeaderValue::from_bool(message_id.is_multiple_of(5))?,
+                HeaderKey::try_from("trace_id")?,
+                (message_id as i128 * 1_000_000_000_000).into(),
             );
             headers.insert(
-                HeaderKey::from_uint32(44)?,
-                HeaderValue::from_float64(message_id as f64 * 2.0)?,
-            );
-            headers.insert(
-                HeaderKey::from_string("trace_id")?,
-                HeaderValue::from_int128(message_id as i128 * 
1_000_000_000_000)?,
-            );
-            headers.insert(
-                HeaderKey::from_raw(&[0xDE, 0xAD])?,
-                HeaderValue::from_raw(&[0xBE, 0xEF, 0xCA, 0xFE])?,
+                HeaderKey::try_from([0xDE, 0xAD].as_slice())?,
+                HeaderValue::try_from([0xBE, 0xEF, 0xCA, 0xFE].as_slice())?,
             );
 
             let payload =
diff --git a/examples/rust/src/shared/codec.rs 
b/examples/rust/src/shared/codec.rs
index b5d5aa1dc..3625be417 100644
--- a/examples/rust/src/shared/codec.rs
+++ b/examples/rust/src/shared/codec.rs
@@ -57,13 +57,13 @@ impl FromStr for Codec {
 impl Codec {
     /// Returns the key to indicate compressed messages as HeaderKey.
     pub fn header_key() -> HeaderKey {
-        HeaderKey::from_string(COMPRESSION_HEADER_KEY)
+        HeaderKey::try_from(COMPRESSION_HEADER_KEY)
             .expect("COMPRESSION_HEADER_KEY is an InvalidHeaderKey.")
     }
 
     /// Returns the compression algorithm type as HeaderValue.
     pub fn to_header_value(&self) -> HeaderValue {
-        HeaderValue::from_str(&self.to_string()).expect("failed generating 
HeaderValue.")
+        HeaderValue::try_from(self.to_string()).expect("failed generating 
HeaderValue.")
     }
 
     /// Returns a Codec from a HeaderValue. Used when reading messages from 
the server.
diff --git a/foreign/csharp/Iggy_SDK/JsonConverters/MessageConverter.cs 
b/foreign/csharp/Iggy_SDK/JsonConverters/MessageConverter.cs
index 4a9331398..43b2163ce 100644
--- a/foreign/csharp/Iggy_SDK/JsonConverters/MessageConverter.cs
+++ b/foreign/csharp/Iggy_SDK/JsonConverters/MessageConverter.cs
@@ -54,11 +54,11 @@ internal sealed class MessageConverter : 
JsonConverter<Message>
     {
         if (userHeaders is null)
         {
-            writer.WriteNull("headers");
+            writer.WriteNull("user_headers");
             return;
         }
 
-        writer.WriteStartArray("headers");
+        writer.WriteStartArray("user_headers");
 
         foreach (var (headerKey, headerValue) in userHeaders)
         {


Reply via email to