#logo #display #macro-derive #macro #string #proc-macro

macro logos-display

基于logos的token和regex属性自动定义Display特质的衍生宏

3个版本

0.1.3 2024年8月11日
0.1.2 2023年9月6日
0.1.1 2023年9月6日
0.1.0 2023年7月15日

1960编码 中排名

Download history 5/week @ 2024-06-03 4/week @ 2024-06-10 7/week @ 2024-06-17 8/week @ 2024-06-24 10/week @ 2024-07-01 7/week @ 2024-07-15 21/week @ 2024-07-29 73/week @ 2024-08-05 55/week @ 2024-08-12

每月下载量149
4 个crate中使用了(通过 wagon-lexer

MIT 许可证

21KB
408

Logos Display

一套衍生宏,根据Logos的token和regex属性自动为枚举实现DisplayDebug,适用于no_std上下文。

如何使用

简单使用use logos_display::Display和/或use logos_display::Debug并将其添加到您的衍生中,如下所示

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]"),
        }
    }
}

DisplayDebug之间的区别

如果枚举变体是单元类型,则没有区别。但如果变体是元组或结构体变体,则Debug版本还将显示实例持有的内部值,而Display版本将只输出外层名称。如下所示

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]),
        }
    }
}

当然,这也要求内部类型以某种形式实现Debug

处理非token

如果变体不是token或regex,则将使用变体名称作为Display方法的名称(因此变体B的字符串表示形式将是"B")。如果您想覆盖任何此功能,可以在变体上添加一个display_override("string")属性,如下所示

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]"),
        }
    }
}

多个token

当变体接受多个token时,默认情况下,它们将在字符串表示中使用/连接,如下所示

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, "{}", "{/}"),
        }
    }
}

该功能可以通过在原始枚举上使用 display_concat("string") 属性来覆盖。

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 }"),
        }
    }
}

此外,您可以将 None 传递给此属性以禁用连接。在这种情况下,将使用遇到的最后一个令牌。

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, "{}", "}"),
        }
    }
}

依赖项

~270–720KB
~17K SLoC