# 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.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