litext 1.2.2

Seamless proc-macro literal extraction.
Documentation
# 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