assert_len!() { /* proc-macro */ }
Expand description
This macro takes a string and a range and asserts that the string’s length lies within this range. Due to the limitations of proc_macros this macro must be used in type position (for the simple check with two arguments), or it must be used in item position (for the extended mode shown below).
This works:
use actyx_sdk_macros::assert_len;
// this is normally emitted by macro_rules
#[allow(dead_code)]
type X = assert_len!(b"A", 1..=1);
This does not compile:
ⓘ
use actyx_sdk_macros::assert_len;
type X = assert_len!(r##"123456"##, ..5);
It is possible to only perform the length check if the argument is a (byte)string literal and emit transformation code depending on whether it was a literal. Due to the restriction on procedural macros (they cannot expand to expressions or statements) we need to wrap the resulting logic in top-level items as shown below:
macro_rules! transform {
($expr:expr) => {{
mod y {
actyx_sdk_macros::assert_len! {
$expr,
1..5,
pub fn x() -> usize { ($expr).len() }, // it was a string literal
pub fn x() -> String { format!("{}", $expr) } // it was something else
}
}
y::x()
}};
}
assert_eq!(transform!("helo"), 4);
assert_eq!(transform!("hello".to_string()), "hello");