From 6d8280018f6ed355c844be95211b36fbe47837d6 Mon Sep 17 00:00:00 2001 From: Nikhil Benesch Date: Fri, 18 Jun 2021 15:17:08 -0400 Subject: [PATCH] Introduce macro to create static UncasedStrs Add a static_uncased_str macro, which can create `&'static UncasedStr`s from `&'static str`s. This won't be necessary once rust-lang/rust#53605 lands, but that's at least a few months away. --- src/borrowed.rs | 17 +++++++++++++++++ src/tests.rs | 8 +++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/borrowed.rs b/src/borrowed.rs index b5f2f1c..467b748 100644 --- a/src/borrowed.rs +++ b/src/borrowed.rs @@ -242,3 +242,20 @@ impl Hash for UncasedStr { self.0.bytes().for_each(|b| hasher.write_u8(b.to_ascii_lowercase())); } } + +/// Cost-free conversion from a `&'static str` to a `&'static UncasedStr`. +/// +/// This macro can be used in the definition of a static or const variable, +/// while [`UncasedStr::new`] cannot. +/// +/// When it is possible to mark `UncasedStr::new` as a `const fn` +/// (see [rust-lang/rust#53605]), this macro will be removed. +/// +/// [rust-lang/rust#53605]: https://github.com/rust-lang/rust/issues/53605 +#[macro_export] +macro_rules! static_uncased_str { + ($string:expr) => {{ + // This is safe for the same reason that `UncasedStr::new` is safe. + unsafe { ::core::mem::transmute::<&'static str, &'static UncasedStr>($string) } + }} +} diff --git a/src/tests.rs b/src/tests.rs index b31f09e..e3f72c8 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,6 +1,6 @@ #![allow(deprecated)] -use crate::UncasedStr; +use crate::{static_uncased_str, UncasedStr}; use core::hash::{Hash, Hasher, SipHasher}; @@ -58,3 +58,9 @@ fn test_case_cmp() { assert!(UncasedStr::new("aA") > UncasedStr::new("a")); assert!(UncasedStr::new("aA") > UncasedStr::new("A")); } + +#[test] +fn test_static() { + const FOO: &UncasedStr = static_uncased_str!("FOO"); + assert_eq!(FOO, UncasedStr::new("foo")); +}