# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.2.2] - 2026-04-29
### Fixed
- Unwrapped metavar groups (commonly emitted by `macro_rules!`) by using a `Delimiter::None` check
and calling `.stream()`. Normal groups with a delimiter other than `Delimiter::None` will still fail.
- Clippysized the code (all, pedantic, nursery)
## [1.2.1] - 2026-04-27
### Fixed
- Error paths in the `litext!` macro now properly convert `proc_macro2::TokenStream`
to `proc_macro::TokenStream`. Previously, when extraction failed and the macro
returned early with an error, the type mismatch would cause compilation issues
in actual proc-macro entry points. This was masked in tests since they run in
a `proc_macro2` context.
## [1.2.0] - 2026-04-27
### Added
- Negative literal support for signed integer and float types. You can now pass
negative numbers like `-42` or `-3.14` directly in the token stream. The `-`
is treated as a punctuation token followed by the literal, and signed types
handle the negation automatically. Works with `i8` through `i128`, `isize`,
`f32`, and `f64`, plus the span aware wrappers `LitInt<T>` and `LitFloat<T>`.
- Proper error messages when unsigned types receive a negative literal, telling
you that you cannot negate an unsigned integer.
- The `from_negative_lit` method on the `FromLit` trait, so you can add
negative literal support to your own custom types if needed.
### Fixed
- The `litext!` macro now converts input with `.into()` so it plays nicely
with `proc_macro::TokenStream` without the user needing to do the conversion
manually.
## [1.1.0] - 2026-04-24
### Added
- Variadic multi-extraction: `litext!(input as (T1 sep T2))` extracts several
typed values from one `TokenStream` in a single call, up to 12 values.
The separator is any single punctuation character that matches what appears
in the actual input.
- `try` form for variadic extraction: `litext!(try input as (T1 sep T2))`
returns `Result<(T1, T2), TokenStream>` instead of returning early.
- All errors across a multi-extraction call are accumulated and reported
together, so users see every problem at once.
### Fixed
- Byte literals (`b'\xff'`, `b'\x80'`) and byte strings (`b"\xff\x80"`)
now correctly accept the full 0x00..=0xFF range for `\x` escapes. Previously
the byte path incorrectly reused the string unescaper, which restricted `\x`
to ASCII (0x00..=0x7F) and rejected valid byte literals above `\x7F`.
- `LitInt<isize>` and `LitInt<usize>` were missing from the `ToTokens`
implementation. They now round-trip correctly.
### Improved
- Test suite expanded to 226 tests covering edge cases across all literal kinds:
high-byte escapes, integer overflow, radix variants, float edge cases, error
message content, round-trip fidelity, and custom `FromLit` implementations.
## [1.0.0] :tada: - 2026-04-23
> [!WARNING]
> **1.0.0 introduces breaking changes.** See the Breaking and Migrating sections below.
### Added
- `extract<T>()` is now generic over `FromLit`, replacing the old `extract_litstr()`.
- `FromLit` trait for implementing custom literal extraction. `litext!(input as MyType)`
now works for any type implementing `FromLit`.
- `ToTokens` trait for converting span-aware types back into `TokenStream`,
enabling round-tripping of literals.
- `LitInt<T>` span-aware integer type, defaulting to `i32`. Supports all radixes
(decimal, hex `0x`, octal `0o`, binary `0b`) and underscore separators.
- `LitFloat<T>` span-aware float type, defaulting to `f64`. Supports scientific
notation, underscore separators, and type suffixes (`f32`, `f64`).
- `LitBool` span-aware boolean type. Handles `true`/`false` as identifiers.
- `LitChar` span-aware character type. Supports escape sequences (`\n`, `\t`, `\\`,
`\'`, `\"`, `\0`, `\x41`, `\u{1F600}`).
- `LitByte` span-aware byte literal type for `b'a'` literals.
- `LitByteStr` span-aware byte string type for `b"..."` and `br#"..."#` literals,
backed by `Vec<u8>`.
- `LitCStr` span-aware C string type for `c"..."` and `cr#"..."#` literals,
backed by `CString`.
- `FromLit` implementations for all primitive integer types (`i8` through `usize`),
float types (`f32`, `f64`), `char`, `bool`, `Vec<u8>`, and `CString`.
- Integer literal parsing supports all radixes: decimal, hex (`0x`/`0X`), octal
(`0o`/`0O`), binary (`0b`/`0B`), uppercase variants, and underscore separators.
- Float literal parsing supports scientific notation (`1e10`, `2.5e-3`),
underscore separators (`1_000.5`), and type suffixes (`3.14_f32`).
- String literal parsing with full escape sequence support: `\n`, `\r`, `\t`,
`\\`, `\"`, `\0`, `\x41` (ASCII hex), and `\u{1F600}` (Unicode).
- Raw string literal parsing (`r#"..."#`) with proper hash-mark handling.
- Byte literal parsing (`b'a'`, `b'\n'`, `b'\xff'`) with escape support.
- Byte string parsing (`b"..."`, `br#"..."#`) with escape support.
- C string parsing (`c"..."`, `cr#"..."#`) with null-byte validation.
- `litext!(try input)` and `litext!(try input as T)` forms that return
`Result<T, TokenStream>` instead of returning early on error.
- `comperr` as a dependency for span-accurate error reporting throughout.
- `proc_macro2` as a dependency, enabling use outside proc-macro contexts and
in unit tests.
### Breaking
- `litext` now depends on `proc_macro2` instead of `proc_macro`. All types
are now from `proc_macro2`.
- `extract_litstr()` has been removed. Use `extract::<LitStr>()` instead.
- `unescape()` now takes a `Span` as a second argument and is no longer
callable with one argument.
### Migrating
- Add `proc_macro2` as a direct dependency to your crate. At your proc-macro
entry point, convert with `.into()`:
```rust
pub fn my_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
my_macro_inner(input.into()).into()
}
fn my_macro_inner(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
let s = litext!(input);
}
```
- Replace any `extract_litstr(input)` calls with `extract::<LitStr>(input)`.
## [0.3.0] - 2026-04-22
> [!WARNING]
> **0.3.0 introduces breaking changes,** look into the Breaking section down below for more information.
### Added
- `litext!(input as LitStr)` form, which returns a `LitStr` bundling the
extracted string value with its source `Span`. Useful for emitting
diagnostics that point at the exact location of the literal.
- `litext!(input as String)` form as a self-documenting alias for the
plain `litext!(input)` form.
- `LitStr` struct with `value()` and `span()` accessors.
- `extract_litstr()` function, the span-aware counterpart to `extract()`.
- Now re-exports `proc_macro::Span`
### Breaking
- `litext!` now accepts `$input:ident` instead of `$input:expr`. The macro
argument must be a bare variable name, arbitrary expressions such as
`litext!(get_stream())` are no longer accepted.
### Migrating
- If you have never called `litext!` with anything other than a bare variable
name, no changes are needed, you're safe!
- Otherwise, assign the expression to a variable first:
```rust
let s = get_stream();
litext!(s);
```
## [0.2.0] - 2024-04-22
### Added
- `unescape`-ing, unescapes the output.
## [0.1.0] - 2024-04-22
### Added
- Comprehensive docstrings for the `litext!` macro and `extract` function
- Byte string rejection for all variants (`b"..."`, `br"..."`, `br#"..."#`, etc.)
- Full README with badges
- Zero dependencies
### Fixed
- Byte string detection to handle raw byte strings with multiple hash marks
## [0.1.0-alpha.1] - 2024-04-15
### Added
- Initial release
- `litext!` macro for extracting string content from TokenStream
- `extract` function for direct TokenStream processing
- Support for regular strings and raw strings with hash marks