Skip to main content

Crate litext

Crate litext 

Source
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 typeAccepted inputNotes
String, LitStr"hello", r#"raw"#Full escape sequence support
i8 to i128, isize, LitInt<T>42, 0xFF, 0b1010, 1_000u32All radixes, underscore separators, type suffixes
u8 to u128, usize, LitInt<T>same as integerOverflow is a compile error
f32, f64, LitFloat<T>3.14, 1e10, 1_000.5f32Scientific notation, underscores, suffixes
char, LitChar'a', '\n', '\u{1F600}'Full Unicode and escape support
bool, LitBooltrue, falseParsed as identifier tokens
u8, LitByteb'a', b'\xff'Full 0x00..=0xFF byte range
Vec<u8>, LitByteStrb"hello", br#"..."#Full byte range for \x escapes
CString, LitCStrc"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

  • The ToTokens round-trip trait
  • FromLit trait for custom literal extraction
  • extract for the lower-level function API

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.
LitByteStr
A parsed byte string literal (b"..." or br#"..."#) bundled with its source location.
LitCStr
A parsed C string literal (c"..." or cr#"..."#) 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 TokenStream containing exactly one literal.