Revision control

Copy as Markdown

Other Tools

# `litrs`: parsing and inspecting Rust literals
`litrs` offers functionality to parse Rust literals, i.e. tokens in the Rust programming language that represent fixed values.
For example: `27`, `"crab"`, `bool`.
This is particularly useful for proc macros, but can also be used outside of a proc-macro context.
**Why this library?**
Unfortunately, the `proc_macro` API shipped with the compiler offers no easy way to inspect literals.
There are mainly two libraries for this purpose:
The latter is deprecated.
And `syn` is oftentimes overkill for the task at hand, especially when developing function-like proc-macros (e.g. `foo!(..)`).
This crate is a lightweight alternative.
Also, when it comes to literals, `litrs` offers a bit more flexibility and a few more features compared to `syn`.
I'm interested in community feedback!
If you consider using this, please speak your mind [in this issue](https://github.com/LukasKalbertodt/litrs/issues/1).
## Example
### In proc macro
```rust
use std::convert::TryFrom;
use proc_macro::TokenStream;
use litrs::Literal;
#[proc_macro]
pub fn foo(input: TokenStream) -> TokenStream {
// Please do proper error handling in your real code!
let first_token = input.into_iter().next().expect("no input");
// `try_from` will return an error if the token is not a literal.
match Literal::try_from(first_token) {
// Convenient methods to produce decent errors via `compile_error!`.
Err(e) => return e.to_compile_error(),
// You can now inspect your literal!
Ok(Literal::Integer(i)) => {
println!("Got an integer specified in base {:?}", i.base());
let value = i.value::<u64>().expect("integer literal too large");
println!("Is your integer even? {}", value % 2 == 0);
}
Ok(other) => {
println!("Got a non-integer literal");
}
}
TokenStream::new() // dummy output
}
```
If you are expecting a specific kind of literal, you can also use this, which will return an error if the token is not a float literal.
```rust
FloatLit::try_from(first_token)
```
### Parsing from a `&str`
Outside of a proc macro context you might want to parse a string directly.
```rust
use litrs::{FloatLit, Literal};
let lit = Literal::parse("'🦀'").expect("failed to parse literal");
let float_lit = FloatLit::parse("2.7e3").expect("failed to parse as float literal");
```
See [**the documentation**](https://docs.rs/litrs) or the `examples/` directory for more examples and information.
<br />
---
## License
Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this project by you, as defined in the Apache-2.0 license,
shall be dual licensed as above, without any additional terms or conditions.