1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
//! # litext
//!
//! A procedural macro library for extracting literal contents from tokens.
//! Built for proc-macro authors who need to pull string, numeric, char, bool,
//! byte, and C string literal contents from `TokenStream` input.
//!
//! ## Overview
//!
//! When writing procedural macros, you often receive tokens that represent literals
//! and need to extract their actual values. This crate provides the [`extract`]
//! function and [`litext!`] macro for this purpose, supporting a wide variety
//! of literal types with span tracking for precise error reporting.
//!
//! ## Features
//!
//! - Extract content from string, raw string, byte string, and C string literals
//! - Parse integer literals (decimal, hex `0xFF`, octal `0o77`, binary `0b1010`)
//! with underscore separators (`1_000`) and type suffixes (`42u8`)
//! - Parse float literals with scientific notation (`1e10`), underscore separators,
//! and type suffixes (`3.14f32`)
//! - Extract character literals with full escape support (`\n`, `\t`, `\\`, `\'`,
//! `\"`, `\0`, `\x41`, `\u{1F600}`)
//! - Extract byte literals (`b'a'`, `b'\xff'`) and byte strings (`b"..."`)
//! - Parse boolean literals (`true`, `false`) from identifiers
//! - Span-aware types (`LitStr`, `LitInt<T>`, `LitFloat<T>`, `LitBool`,
//! `LitChar`, `LitByte`, `LitByteStr`, `LitCStr`) for precise error reporting
//! - Round-trip support via [`ToTokens`] trait
//! - Extensible via the [`FromLit`] trait for custom types
//! - Result-returning variants via the `try` keyword for flexible error handling
//!
//! ## Quick Start
//!
//! ```ignore
//! use litext::{litext, TokenStream};
//!
//! fn my_macro(input: TokenStream) -> TokenStream {
//! // Using the macro with try to get a Result (recommended for error handling)
//! let result: Result<String, TokenStream> = litext!(try input);
//! match result {
//! Ok(text) => quote::quote! { /* use text */ },
//! Err(e) => e, // Forward the error
//! };
//!
//! // Or return early on error (convenient, concise)
//! let text: String = litext!(input);
//! quote::quote! { /* use text */ }
//! }
//! ```
//!
//! ## Literal Types Supported
//!
//! | Target Type | Example Input | Extracted Value |
//! |-------------|---------------|----------------|
//! | `String`, `LitStr` | `"hello"`, `r#"raw"#` | String content |
//! | Integer types, `LitInt<T>` | `42`, `0xFF_i32`, `0b1010` | Parsed integer |
//! | Float types, `LitFloat<T>` | `3.14`, `1e10_f32` | Parsed float |
//! | `char`, `LitChar` | `'x'`, `'\n'`, `'\u{1F600}'` | Unicode character |
//! | `bool`, `LitBool` | `true`, `false` | Boolean value |
//! | `u8`, `LitByte` | `b'a'`, `b'\xff'` | Byte value |
//! | `Vec<u8>`, `LitByteStr` | `b"hello"`, `br#"..."#` | Byte vector |
//! | `CString`, `LitCStr` | `c"hello"`, `cr#"..."#` | C string |
//!
//! ## See Also
//!
//! - Span-aware literal types and `ToTokens` trait for round-tripping
//! - [`FromLit`] trait for implementing custom literal parsing
use ;
pub use *;
/// A convenience macro for extracting string literal content from a token stream.
///
/// This macro is the primary entry point for extracting literal content in proc-macro
/// implementations. It wraps [`extract`] and returns early with a compile error if
/// extraction fails.
///
/// # Syntax
///
/// ```ignore
/// litext!(input) // Extract as String
/// litext!(input as String) // Extract as String (explicit)
/// litext!(input as T) // Extract as custom type T implementing FromLit
/// litext!(try input) // Extract as String, keep Result
/// litext!(try input as T) // Extract as T, keep Result
/// ```
///
/// # Arguments
///
/// - `input` - An expression that evaluates to a `TokenStream`
/// - `as T` - Optional: the target type to extract into. Defaults to `String` if omitted.
/// - `try` - Optional: when present, returns `Result<T, TokenStream>` instead of
/// returning early on error. Useful when you want to handle errors differently.
///
/// # Behavior
///
/// - Without `try`: Passes the input to [`extract::<T>`]. If extraction succeeds,
/// returns the value. If extraction fails, returns the error `TokenStream`.
/// - With `try`: Returns `Result<T, TokenStream>` from [`extract`], allowing you
/// to handle success and error cases explicitly.
///
/// # Examples
///
/// ```ignore
/// use litext::{litext, TokenStream};
///
/// fn my_string_macro(input: TokenStream) -> TokenStream {
/// // Extract a string literal, return early on error
/// let text: String = litext!(input);
/// quote::quote! { /* use text */ }
/// }
///
/// fn my_int_macro(input: TokenStream) -> TokenStream {
/// // Extract an integer literal, return early on error
/// let num: i32 = litext!(input as i32);
/// quote::quote! { /* use num */ }
/// }
///
/// fn my_custom_macro(input: TokenStream) -> TokenStream {
/// // Extract as a custom type, return early on error
/// let lit: LitStr = litext!(input as LitStr);
/// quote::quote! { #lit }
/// }
///
/// fn my_try_macro(input: TokenStream) -> TokenStream {
/// // Extract but handle error explicitly
/// let result: Result<String, TokenStream> = litext!(try input);
/// match result {
/// Ok(text) => quote::quote! { /* use text */ },
/// Err(e) => e, // Forward the error
/// }
/// }
/// ```
///
/// # See Also
///
/// - [`extract`] for extracting without the macro wrapper
/// - [`FromLit`] for implementing custom extraction behavior
/// Extracts the inner value from a token stream representing a literal.
///
/// This function is the core of the crate. It takes a `TokenStream` and attempts to
/// extract a single literal token, then converts it to the target type `T` using
/// the [`FromLit`] trait.
///
/// # Type Parameter
///
/// - `T` - The target type implementing [`FromLit`]. Supported types include:
/// - `String`, `LitStr` - String and raw string literals
/// - `i8`–`i128`, `u8`–`u128`, `isize`, `usize`, `LitInt<T>` - Integer literals
/// - `f32`, `f64`, `LitFloat<T>` - Float literals
/// - `char`, `LitChar` - Character literals
/// - `bool`, `LitBool` - Boolean literals (from `true`/`false` identifiers)
/// - `u8`, `LitByte` - Byte literals (`b'a'`)
/// - `Vec<u8>`, `LitByteStr` - Byte string literals (`b"..."`)
/// - `CString`, `LitCStr` - C string literals (`c"..."`)
///
/// # Arguments
///
/// - `input` - A `TokenStream` that should contain exactly one literal token or identifier
///
/// # Limitations
///
/// - Negative numbers like `-42` are not literals in Rust's token stream -- they are
/// two tokens (a `-` punct and a positive literal). `extract` does not support
/// them. Handle negation at the expression level instead.
///
/// # Return Value
///
/// - `Ok(T)` - The extracted value of type `T`
/// - `Err(TokenStream)` - An error token stream that will trigger a compile error
/// when returned from a proc-macro. This occurs when:
/// - The input is empty
/// - The input contains more than one token
/// - The input is not a recognized literal or identifier
/// - The literal cannot be parsed as the target type (e.g., overflow)
///
/// # What Can Be Extracted
///
/// | Target Type | Accepted Inputs |
/// |-------------|-----------------|
/// | `String`, `LitStr` | `"hello"`, `r#"raw"#"`, `r"C:\path"` |
/// | `i8`–`i128`, `u8`–`u128`, `isize`, `usize` | `42`, `0xFF`, `0o77`, `0b1010`, `1_000`, `42_i32` |
/// | `f32`, `f64` | `3.14`, `1e10`, `1.0_f32`, `1_000.5` |
/// | `char`, `LitChar` | `'a'`, `'\n'`, `'\u{1F600}'`, `'\x41'` |
/// | `bool`, `LitBool` | `true`, `false` (as identifiers) |
/// | `u8`, `LitByte` | `b'a'`, `b'\n'`, `b'\xff'` |
/// | `Vec<u8>`, `LitByteStr` | `b"hello"`, `br#"raw"#` |
/// | `CString`, `LitCStr` | `c"hello"`, `cr#"raw"#` |
///
/// # Error Handling
///
/// This function does not panic. All errors are returned as `TokenStream` values
/// containing error tokens. When returned from a proc-macro entry point function,
/// these error tokens cause the compiler to display the error message and abort
/// compilation.
///
/// # Examples
///
/// ```ignore
/// use litext::{extract, TokenStream};
///
/// fn process_string(input: TokenStream) -> Result<String, TokenStream> {
/// extract::<String>(input)
/// }
///
/// fn process_int(input: TokenStream) -> Result<i64, TokenStream> {
/// extract::<i64>(input)
/// }
///
/// fn process_float(input: TokenStream) -> Result<f64, TokenStream> {
/// extract::<f64>(input)
/// }
///
/// fn process_char(input: TokenStream) -> Result<char, TokenStream> {
/// extract::<char>(input)
/// }
///
/// fn process_custom(input: TokenStream) -> Result<LitStr, TokenStream> {
/// extract::<LitStr>(input)
/// }
/// ```
///
/// # See Also
///
/// - [`litext!`] macro for a convenient wrapper that returns early on error
/// - [`FromLit`] trait for the conversion logic
/// - Span-aware types and `ToTokens` trait for round-tripping
/// Parses a string literal token and returns the unescaped content.
pub
/// Extracts the inner content from a raw string literal like `r#"..."#`.
pub
/// Processes escape sequences in a string and returns the unescaped result.
pub