将枚举类型转换为字符串,使用 impl fmt::Display

3

我正在使用Rust创建一个错误代码枚举。

pub enum ErrorCode {
    InvalidUsername,
    InvalidPassword,
}

我希望这个枚举类型能够在使用actix_web时用于JSON响应,因此我需要将枚举类型转换为字符串。

为此,我尝试在ErrorCode枚举类型上实现fmt::Display

#[derive(Debug)]
pub enum ErrorCode {
    InvalidUsername,
    InvalidPassword,
}

impl fmt::Display for ErrorCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", *self)
     }
}

但每当我尝试在 ErrorCode 上运行 .to_string() 时,程序都会崩溃并进入无限循环。

thread 'actix-rt:worker:0' has overflowed its stack
fatal runtime error: stack overflow
[1]    85991 abort      ./target/debug/app

我希望将枚举转换为字符串,并能够在 impl fmt :: Display 中对该字符串进行更改,这样我就可以将其转换为 snake_case 等格式。


1
你可能正在寻找类似于strum的东西,它引入了过程宏,您可以使用这些宏为枚举类型派生出Display trait(以及其他trait),并提供许多自定义选项。您还可以选择通过修改和返回由strum宏实现的另一个方法的输出来自己实现Display,例如AsRefStr - EvilTak
1个回答

1

fmt()函数内部调用write!()来使用{}替换为self是不可行的,因为这个宏会调用完全相同的函数,从而创建无限循环。

相反,你应该使用函数f: &mut fmt::Formatter的参数来编写所需的结果。

match self {
  ErrorCode::InvalidUsername => f.write_str("Invalid user name"),
  ...
}

同时也有一些库可以帮助你减少这种情况下的样板代码。如strum,正如EvilTak所建议的那样。


谢谢你和@EvilTak的帮助,最终我选择了strum,并且它完美地解决了我的问题。 - Ari Seyhun
5
fmt函数中完全可以调用write!官方文档的示例就是这样做的。问题在于它正在对正在实现的 self 执行 Display,而由于 Display 实现仅仅是在不断递归自身而没有做任何有用的事情,所以导致程序崩溃。委托给Debug就可以正常工作 - Masklinn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接