logos-display 0.1.3

A derive macro to automatically define the Display trait based on logos `token` and `regex` attributes.
Documentation
# 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, "{}", "}"),
        }
    }
}
```