Skip to content

Commit d46f745

Browse files
caspervonbJarema
authored andcommitted
Add static representation for custom header names
1 parent f30b3ec commit d46f745

File tree

1 file changed

+63
-3
lines changed

1 file changed

+63
-3
lines changed

async-nats/src/header.rs

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

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

1819
/// A struct for handling NATS headers.
@@ -265,7 +266,7 @@ pub trait IntoHeaderName {
265266
impl IntoHeaderName for &str {
266267
fn into_header_name(self) -> HeaderName {
267268
HeaderName {
268-
inner: HeaderRepr::Custom(self.to_string()),
269+
inner: HeaderRepr::Custom(self.into()),
269270
}
270271
}
271272
}
@@ -385,10 +386,47 @@ standard_headers! {
385386
(NatsExpectedStream, NATS_EXPECTED_STREAM, b"Nats-Expected-Stream");
386387
}
387388

389+
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
390+
struct CustomHeader {
391+
bytes: Bytes,
392+
}
393+
394+
impl CustomHeader {
395+
#[inline]
396+
pub(crate) const fn from_static(value: &'static str) -> CustomHeader {
397+
CustomHeader {
398+
bytes: Bytes::from_static(value.as_bytes()),
399+
}
400+
}
401+
402+
#[inline]
403+
pub(crate) fn as_str(&self) -> &str {
404+
unsafe { std::str::from_utf8_unchecked(self.bytes.as_ref()) }
405+
}
406+
}
407+
408+
impl From<String> for CustomHeader {
409+
#[inline]
410+
fn from(value: String) -> CustomHeader {
411+
CustomHeader {
412+
bytes: Bytes::from(value),
413+
}
414+
}
415+
}
416+
417+
impl<'a> From<&'a str> for CustomHeader {
418+
#[inline]
419+
fn from(value: &'a str) -> CustomHeader {
420+
CustomHeader {
421+
bytes: Bytes::copy_from_slice(value.as_bytes()),
422+
}
423+
}
424+
}
425+
388426
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
389427
enum HeaderRepr {
390428
Standard(StandardHeader),
391-
Custom(String),
429+
Custom(CustomHeader),
392430
}
393431

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

399437
impl HeaderName {
438+
/// Converts a static string to a NATS header name.
439+
#[inline]
440+
pub const fn from_static(value: &'static str) -> HeaderName {
441+
if let Some(standard) = StandardHeader::from_bytes(value.as_bytes()) {
442+
return HeaderName {
443+
inner: HeaderRepr::Standard(standard),
444+
};
445+
}
446+
447+
HeaderName {
448+
inner: HeaderRepr::Custom(CustomHeader::from_static(value)),
449+
}
450+
}
451+
400452
/// Returns a `str` representation of the header.
401453
#[inline]
402454
fn as_str(&self) -> &str {
@@ -420,7 +472,7 @@ impl FromStr for HeaderName {
420472
inner: HeaderRepr::Standard(v),
421473
}),
422474
None => Ok(HeaderName {
423-
inner: HeaderRepr::Custom(s.to_string()),
475+
inner: HeaderRepr::Custom(CustomHeader::from(s)),
424476
}),
425477
}
426478
}
@@ -572,4 +624,12 @@ mod tests {
572624
parsed_header.ok()
573625
);
574626
}
627+
628+
#[test]
629+
fn from_static_eq() {
630+
let a = HeaderName::from_static("NATS-Stream");
631+
let b = HeaderName::from_static("NATS-Stream");
632+
633+
assert_eq!(a, b);
634+
}
575635
}

0 commit comments

Comments
 (0)