1 stable release
1.0.0 | Sep 14, 2023 |
---|
#1663 in Procedural macros
10KB
125 lines
typeof-literal
A macro that gets the type of any literal or primitive expression
lib.rs
:
typeof_literal
is a macro that can get the type of any literal or
composite-of-literals expression. It can be used to help with trait
implementations or function definitions that are generated by macros, where the
macro has access to some literal value but still needs to name the type in a
function return or trait associated type.
Example
use typeof_literal::typeof_literal;
/// This macro creates a `const fn` called `$name` that returns `$value`.
macro_rules! maker {
($name:ident => $value:expr) => {
const fn $name() -> typeof_literal!{$value} {
$value
}
}
}
maker! {ten => 10i16}
let value: i16 = ten();
assert_eq!(value, 10);
maker! {hello_world => "Hello, World"}
assert_eq!(hello_world(), "Hello, World");
// It works on composite types
maker! {tuple => (123, [0u8; 2], [1i64, 2, 3, 4], "Hello")};
assert_eq!(tuple(), (123i32, [0, 0], [1, 2, 3, 4], "Hello"));
// It also works on common macro literal-ish expressions
maker! {concatenated => concat!(1, 2, 3, "abc")}
assert_eq!(concatenated(), "123abc");
// We support blocks and other nested expressions, and can use `as` to support
// *any* arbitrary expression
maker! {computed => {
let x = 1;
let y = 2;
(x + y) as i32
}}
assert_eq!(computed(), 3);
In these examples, the maker
macro is used to create a function that returns
a literal value. typeof_literal
allows us to automatically know the type of
that literal, so that we can use it for the function's return type, instead of
forcing the caller to include it with something like
maker!(int => 123 as i64)
.
Currently it only works on primitive literals and composites of literals. In
the future we may add support for simple binary operations like 1 + 2
, struct
literals, etc.
Dependencies
~265–720KB
~17K SLoC