Skip to content

Commit

Permalink
Add static representation for custom header names
Browse files Browse the repository at this point in the history
  • Loading branch information
caspervonb authored and Jarema committed May 30, 2023
1 parent f30b3ec commit d46f745
Showing 1 changed file with 63 additions and 3 deletions.
66 changes: 63 additions & 3 deletions async-nats/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

//! NATS [Message][crate::Message] headers, modeled loosely after the [http::header] crate.
use bytes::Bytes;
use std::{collections::HashMap, fmt, slice, str::FromStr};

/// A struct for handling NATS headers.
Expand Down Expand Up @@ -265,7 +266,7 @@ pub trait IntoHeaderName {
impl IntoHeaderName for &str {
fn into_header_name(self) -> HeaderName {
HeaderName {
inner: HeaderRepr::Custom(self.to_string()),
inner: HeaderRepr::Custom(self.into()),
}
}
}
Expand Down Expand Up @@ -385,10 +386,47 @@ standard_headers! {
(NatsExpectedStream, NATS_EXPECTED_STREAM, b"Nats-Expected-Stream");
}

#[derive(Debug, Hash, PartialEq, Eq, Clone)]
struct CustomHeader {
bytes: Bytes,
}

impl CustomHeader {
#[inline]
pub(crate) const fn from_static(value: &'static str) -> CustomHeader {
CustomHeader {
bytes: Bytes::from_static(value.as_bytes()),
}
}

#[inline]
pub(crate) fn as_str(&self) -> &str {
unsafe { std::str::from_utf8_unchecked(self.bytes.as_ref()) }
}
}

impl From<String> for CustomHeader {
#[inline]
fn from(value: String) -> CustomHeader {
CustomHeader {
bytes: Bytes::from(value),
}
}
}

impl<'a> From<&'a str> for CustomHeader {
#[inline]
fn from(value: &'a str) -> CustomHeader {
CustomHeader {
bytes: Bytes::copy_from_slice(value.as_bytes()),
}
}
}

#[derive(Debug, Hash, PartialEq, Eq, Clone)]
enum HeaderRepr {
Standard(StandardHeader),
Custom(String),
Custom(CustomHeader),
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
Expand All @@ -397,6 +435,20 @@ pub struct HeaderName {
}

impl HeaderName {
/// Converts a static string to a NATS header name.
#[inline]
pub const fn from_static(value: &'static str) -> HeaderName {
if let Some(standard) = StandardHeader::from_bytes(value.as_bytes()) {
return HeaderName {
inner: HeaderRepr::Standard(standard),
};
}

HeaderName {
inner: HeaderRepr::Custom(CustomHeader::from_static(value)),
}
}

/// Returns a `str` representation of the header.
#[inline]
fn as_str(&self) -> &str {
Expand All @@ -420,7 +472,7 @@ impl FromStr for HeaderName {
inner: HeaderRepr::Standard(v),
}),
None => Ok(HeaderName {
inner: HeaderRepr::Custom(s.to_string()),
inner: HeaderRepr::Custom(CustomHeader::from(s)),
}),
}
}
Expand Down Expand Up @@ -572,4 +624,12 @@ mod tests {
parsed_header.ok()
);
}

#[test]
fn from_static_eq() {
let a = HeaderName::from_static("NATS-Stream");
let b = HeaderName::from_static("NATS-Stream");

assert_eq!(a, b);
}
}

0 comments on commit d46f745

Please sign in to comment.