#枚举 #特性 #try-from #derive #定制 #

renum

使用定制从枚举派生From或TryFrom特性

2个版本

0.1.1 2022年11月28日
0.1.0 2022年11月27日

#593 in 进程宏

MIT/Apache

29KB
632

Renum

为具有整数值的枚举派生From或TryFrom特性。

设计用于提供一种一致的方法来处理Rust中的C样式枚举,例如在实现解析器时。

使用方法

[dependencies]
renum = "0.1.0"
use renum::Renum;

#[derive(Debug, Clone, Copy, Renum)]
#[renum(TryFrom)]
pub enum MyEnum {
  VariantA = 0x01,
  VariantB = 0x02,
  VariantC = 0x03,
  Undefined
}

let x = MyEnum::try_from(0x04);

assert_eq!(x, Err(MyEnum::Undefined))

枚举选项

normally_ok

默认行为

#[renum(normally_ok)]

派生的try_from返回的Result将是Ok(Enum::Variant),除非显式标记为#[renum(Err)]

除非显式标记为#[renum(Ok)],否则默认情况将返回Err(Enum::Default)

normally_err

#[renum(normally_err)]

反转normally_ok的行为

派生的try_from返回的Result将是Err(Enum::Variant),除非显式标记为#[renum(Ok)]

默认情况下将返回 Ok(Enum::Default),除非显式标记 #[renum(Err)]

示例用法:状态码枚举

#[derive(Renum)]
#[renum(normally_err)]
pub enum StatusCodes {
  Success,
  FailureA = 1,
  FailureB = 2,
  FailureC = 3
}

// ...

let status_code = StatusCodes::try_from(2)?;

allow_panic

#[renum(allow_panic)]

如果枚举没有默认变体 allow_panic,则允许派生方法在未定义值上崩溃。

示例

#[repr(u8)]
#[derive(Renum)
#[renum(allow_panic)]
pub enum PanicEnum {
	A = 0,
	B = 1,
}

#[renum(should_panic)]
fn test() {
	let _ = PanicEnum::from(0xff);
}

错误

仅在派生 TryFrom 时有效

#[renum(Error = REPR)]
#[renum(Error = ENUM)]
#[renum(Error = Other)] // custom

可以使用 Error 选项控制错误类型;REPRENUM 是内置值,它们返回传入的值或枚举变体。

如果使用自定义错误,则必须实现 From::<#ErrorFrom>(下文讨论),默认情况下这将是 repr 类型。

ErrorFrom

仅在派生 TryFrom 时有效

#[renum(ErrorFrom = REPR)]
#[renum(ErrorFrom = ENUM)]
#[renum(ErrorFrom = (ENUM, REPR))]

用于初始化自定义错误的值可以设置为 REPRENUM 或任何 ([REPR|ENUM],*) 的序列

示例


struct CustomError;

impl From<(MyEnum, u16)> for CustomError {
	fn from(from: (MyEnum, u16)) -> Self {
		CustomError;
	}
}

#[repr(u16)]
#[derive(Renum)]
#[renum(TryFrom, ErrorType = CustomError, ErrorFrom = (ENUM, REPR))]
pub enum MyEnum {
	A = 1,
	B = 2,
	C = 3,
	#[renum(Err, values = 4..=34 )]
	ReservedSome,
	#[renum(Err)]
	ReservedRest
}

if let Err(error) = MyEnum::try_from(64) {
	// do something with custom error
}

	

变体选项

Ok

仅在派生 TryFrom 时有效

#[renum(Ok)]
Variant = 0

即使它通常是一个错误条件,变体也总会返回 Ok(Enum::Variant) 当匹配时。

Err

仅在派生 TryFrom 时有效

#[renum(Err)]
Variant = 0

即使它通常是一个错误条件,变体也总会返回 Err(Enum::Variant) 当匹配时。

Default

#[renum(default)]
Variant

如果没有值匹配此变体,将返回此变体;如果没有显式使用 default 选项标记任何变体,则默认选择没有描述符或值属性的变体。

Values

#[renum(values = 10)]     // this shouldn't be needed, use a discriminant
#[renum(values = ..10)]   // REPR::MIN to 9 
#[renum(values = ..=10)]  // REPR::MIN to 10
#[renum(values = 5..10)]  // Range 5 to 9
#[renum(values = 5..=10)] // RangeInclusive 5 to 10
#[renum(values = [0, 15..20, 25..30, 45])] // any combination of values for non-consecutive ranges

指定可能具有多个值的变体的值。

Dependencies

~1.5MB
~35K SLoC