# Logos Display
A set of derive macros that automatically implement `Display` and `Debug` for an enum, based on the [Logos](https://github.com/maciejhirsz/logos) `token` and `regex` attributes. Usable in `no_std` contexts.
## How To Use
Simply `use logos_display::Display` and/or `use logos_display::Debug` and add it to your derives, like so:
```rust
use logos_display::{Display, Debug}
#[derive(Display, Debug, Logos)]
enum A {
#[token("{")]
LCur,
#[regex("[a-z]")]
Lower
}
|
V
impl core::fmt::Display for A {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use core::fmt::Write;
match &self {
A::LCur => write!(f, "{}", "{"),
A::Lower => write!(f, "{}", "[a-z]"),
}
}
}
```
## Difference between `Display` and `Debug`
If the enum variant is a unit type, there is no difference. But in the case where the variant is a tuple or struct variant, the `Debug` version will also show the inner value held by the instance, whereas the `Display` version will only output the name of the outer layer. Like so:
```rust
use logos_display::{Display, Debug}
#[derive(Display, Debug, Logos)]
enum A {
#[token("{")]
LCur,
#[regex("[a-z]", |lex| some_func(lex.slice()))]
Lower(TypeOne, TypeTwo)
}
|
V
impl core::fmt::Debug for A {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use core::fmt::Write;
match &self {
A::LCur => write!(f, "{}", "{"),
A::Lower(_arg1, _arg2) => write!(f, "{}{:?}", "[a-z]", vec![_arg1, _arg2]),
}
}
}
```
This does of course require the inner types to implement `Debug` in some form as well.
### Dealing with non-tokens
In the case that a variant is not a token or regex, the name of the variant will be used for the Display method (so variant `B` will have `"B"` as it's string representation). If you want to override any of this functionality, you can add an `display_override("string")` attribute to the variant as follows:
```rust
use logos_display::Display
#[derive(Display, Logos)]
enum A {
#[display_override("fancy curly thing")]
#[token("{")]
LCur,
#[regex("[a-z]")]
Lower
}
|
V
impl core::fmt::Display for A {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use core::fmt::Write;
match &self {
A::LCur => write!(f, "{}", "fancy curly thing"),
A::Lower => write!(f, "{}", "[a-z]"),
}
}
}
```
### Multiple tokens
When a variant accepts multiple tokens, by default, they will be concatenated using `/` in the string representation, like so:
```rust
use logos_display::Display
#[derive(Display, Logos)]
enum A {
#[token("{")]
#[token("}")]
Cur
}
|
V
impl core::fmt::Display for A {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use core::fmt::Write;
match &self {
A::LCur => write!(f, "{}", "{/}"),
}
}
}
```
This functionality can be overwritten using the `display_concat("string")` attribute on the original enum:
```rust
use logos_display::Display
#[derive(Display, Logos)]
#[display_concat(" or ")]
enum A {
#[token("{")]
#[token("}")]
Cur
}
|
V
impl core::fmt::Display for A {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use core::fmt::Write;
match &self {
A::LCur => write!(f, "{}", "{ or }"),
}
}
}
```
Additionally, you can pass `None` to this attribute in order to disable concatonation. In this case, the token that is encountered last will be used:
```rust
use logos_display::Display
#[derive(Display, Logos)]
#[display_concat(None)]
enum A {
#[token("{")]
#[token("}")]
Cur
}
|
V
impl core::fmt::Display for A {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
use core::fmt::Write;
match &self {
A::LCur => write!(f, "{}", "}"),
}
}
}
```