Skip to content

Commit 5cad42c

Browse files
committed
Implemented macro for compile time non empty string creation
This is more convenient for constant strings in the codebase that are known to be non empty.
1 parent e890aa2 commit 5cad42c

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ serde = { version = "1", features = ["derive"] }
2525

2626
[features]
2727
default = []
28+
macro = []
2829
serde = ["dep:serde"]
2930

3031

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ use delegate::delegate;
1717
#[cfg(feature = "serde")]
1818
mod serde_support;
1919

20+
#[cfg(feature = "macro")]
21+
mod macros;
22+
2023
mod trait_impls;
2124

2225
/// A simple String wrapper type, similar to NonZeroUsize and friends.

src/macros.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#[macro_export]
2+
/// Creates a `NonEmptyString` from a string literal at compile time.
3+
///
4+
/// This macro ensures that the provided string is **not empty** at compile time,
5+
/// preventing runtime errors due to empty strings.
6+
///
7+
/// # Examples
8+
///
9+
/// ```
10+
/// use non_empty_string::{non_empty, NonEmptyString};
11+
///
12+
/// let s: NonEmptyString = non_empty!("Hello, Rust!");
13+
/// assert_eq!(s, NonEmptyString::new("Hello, Rust!".to_string()).unwrap());
14+
/// ```
15+
///
16+
/// # Compile-time Failure
17+
///
18+
/// If an empty string is provided, this macro will cause a **compile-time error**.
19+
///
20+
/// ```compile_fail
21+
/// use non_empty_string::non_empty;
22+
///
23+
/// let s = non_empty!("");
24+
/// ```
25+
macro_rules! non_empty {
26+
($s:expr) => {{
27+
// Compile-time assertion to ensure the string is non-empty
28+
const _: () = assert!(!$s.is_empty(), "String cannot be empty");
29+
30+
// Create a NonEmptyString, unsafely wrapping since we've checked it's valid
31+
unsafe { NonEmptyString::new_unchecked($s.to_string()) }
32+
}};
33+
}
34+
35+
#[cfg(test)]
36+
mod tests {
37+
use crate::NonEmptyString;
38+
39+
#[test]
40+
fn test_non_empty_string_macro_valid() {
41+
let s = non_empty!("Test String");
42+
assert_eq!(s, NonEmptyString::try_from("Test String").unwrap());
43+
}
44+
}

0 commit comments

Comments
 (0)