Expand description
§litext
litext (lee-text /ˈliː.tɛkst/) is a crate for extracting literal values for procedural macros. It’s clean, easy, extendable, and fits in a singular line.
§Overview
Procedural macros frequently receive a TokenStream that contains one or
more literal tokens and need to extract their actual values. This crate
provides the litext! macro and extract function for that purpose,
supporting every Rust literal kind with span tracking for precise diagnostics.
You can also make your own ‘literal type’ that litext treats as something to extract,
using the FromLit trait. Parse your own type from a Rust literal, a negative literal,
or even an identifier, and the macro picks it up like nothing ever happened.
§Quick Start
use litext::{litext, TokenStream};
fn my_macro(input: TokenStream) -> TokenStream {
// Return early with a compile error on failure:
let text: String = litext!(input);
// Or keep the Result for explicit handling:
let result: Result<String, TokenStream> = litext!(try input);
// Extract a non-string type:
let count: u32 = litext!(input as u32);
// Extract multiple literals from one TokenStream:
// (input must be: "name" , 42)
let (name, count): (String, u32) = litext!(input as (String, u32));
}§Supported Literal Types
| Target type | Accepted input | Notes |
|---|---|---|
String, LitStr | "hello", r#"raw"# | Full escape sequence support |
i8 to i128, isize, LitInt<T> | 42, 0xFF, 0b1010, 1_000u32 | All radixes, underscore separators, type suffixes |
u8 to u128, usize, LitInt<T> | same as integer | Overflow is a compile error |
f32, f64, LitFloat<T> | 3.14, 1e10, 1_000.5f32 | Scientific notation, underscores, suffixes |
char, LitChar | 'a', '\n', '\u{1F600}' | Full Unicode and escape support |
bool, LitBool | true, false | Parsed as identifier tokens |
u8, LitByte | b'a', b'\xff' | Full 0x00..=0xFF byte range |
Vec<u8>, LitByteStr | b"hello", br#"..."# | Full byte range for \x escapes |
CString, LitCStr | c"hello", cr#"..."# | Interior null bytes are a compile error |
§Span-Aware Types
Every literal kind has a span-aware wrapper that bundles the parsed value with its source location. Use these when you need to emit diagnostics that point at the exact literal in the user’s code.
use litext::literal::{LitStr, LitInt};
let name: LitStr = litext!(input as LitStr);
if name.value().is_empty() {
return comperr::error(name.span(), "name cannot be empty");
}
let count: LitInt<u32> = litext!(input as LitInt<u32>);
if *count.value() == 0 {
return comperr::error(count.span(), "count must be non-zero");
}§Multi-Extraction
Extract several literals from one TokenStream in a single call by wrapping
the target types in a tuple with the separator token between them:
// input: "hello" , 42
let (s, n): (String, i32) = litext!(input as (String, i32));
// input: "key" ; 100
let (k, v): (String, u32) = litext!(input as (String ; u32));
// input: "key" -> 100 (two-character separator)
let (k, v): (String, u32) = litext!(input as (String -> u32));
// Try form: returns Result instead of returning early
let result: Result<(String, i32), _> = litext!(try input as (String , i32));Up to 12 values can be extracted per call. Type arguments in tuple position
must be single-token identifiers; LitInt<u8> does not fit. Use LitInt
(which defaults to i32) or a plain integer type instead.
§Limitations
Negative numbers like -42 are two tokens in Rust’s token stream: a -
punctuation token and a positive literal. extract and litext! handle
this case for signed integer and float types. Unsigned types will return
a compile error if a negative literal is given.
§See Also
Macros§
- litext
- The whole point.
Structs§
- LitBool
- A parsed boolean literal bundled with its source location.
- LitByte
- A parsed byte literal (
b'...') bundled with its source location. - LitByte
Str - A parsed byte string literal (
b"..."orbr#"..."#) bundled with its source location. - LitCStr
- A parsed C string literal (
c"..."orcr#"..."#) bundled with its source location. - LitChar
- A parsed character literal bundled with its source location.
- LitFloat
- A parsed float literal bundled with its source location.
- LitInt
- A parsed integer literal bundled with its source location.
- LitStr
- A parsed string literal bundled with its source location.
Traits§
- FromLit
- Converts literal tokens into typed values.
- ToTokens
- Converts a span-aware literal type back into a
TokenStream.
Functions§
- extract
- Extracts a typed value from a
TokenStreamcontaining exactly one literal.