Skip to content

Commit 5ac2ed7

Browse files
add ConstTryFromPrimitive
1 parent 6cd542d commit 5ac2ed7

File tree

4 files changed

+710
-14
lines changed

4 files changed

+710
-14
lines changed

num_enum/src/lib.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
#![cfg_attr(not(feature = "std"), no_std)]
99

1010
pub use ::num_enum_derive::{
11-
ConstFromPrimitive, ConstIntoPrimitive, Default, FromPrimitive, IntoPrimitive,
12-
TryFromPrimitive, UnsafeFromPrimitive,
11+
ConstFromPrimitive, ConstIntoPrimitive, ConstTryFromPrimitive, Default, FromPrimitive,
12+
IntoPrimitive, TryFromPrimitive, UnsafeFromPrimitive,
1313
};
1414

1515
use ::core::fmt;
@@ -29,6 +29,13 @@ pub trait TryFromPrimitive: Sized {
2929
fn try_from_primitive(number: Self::Primitive) -> Result<Self, Self::Error>;
3030
}
3131

32+
pub trait ConstTryFromPrimitive: Sized {
33+
type Primitive: Copy + Eq + fmt::Debug;
34+
type Error;
35+
36+
const NAME: &'static str;
37+
}
38+
3239
pub trait UnsafeFromPrimitive: Sized {
3340
type Primitive: Copy + Eq;
3441

@@ -85,6 +92,38 @@ impl<Enum: TryFromPrimitive> fmt::Display for TryFromPrimitiveError<Enum> {
8592
#[cfg(feature = "std")]
8693
impl<Enum: TryFromPrimitive> ::std::error::Error for TryFromPrimitiveError<Enum> {}
8794

95+
#[derive(Copy, Clone, PartialEq, Eq)]
96+
pub struct ConstTryFromPrimitiveError<Enum: ConstTryFromPrimitive> {
97+
pub number: Enum::Primitive,
98+
}
99+
100+
impl<Enum: ConstTryFromPrimitive> ConstTryFromPrimitiveError<Enum> {
101+
pub const fn new(number: Enum::Primitive) -> Self {
102+
Self { number }
103+
}
104+
}
105+
106+
impl<Enum: ConstTryFromPrimitive> fmt::Debug for ConstTryFromPrimitiveError<Enum> {
107+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
108+
fmt.debug_struct("ConstTryFromPrimitiveError")
109+
.field("number", &self.number)
110+
.finish()
111+
}
112+
}
113+
impl<Enum: ConstTryFromPrimitive> fmt::Display for ConstTryFromPrimitiveError<Enum> {
114+
fn fmt(&self, stream: &'_ mut fmt::Formatter<'_>) -> fmt::Result {
115+
write!(
116+
stream,
117+
"No discriminant in enum `{name}` matches the value `{input:?}`",
118+
name = Enum::NAME,
119+
input = self.number,
120+
)
121+
}
122+
}
123+
124+
#[cfg(feature = "std")]
125+
impl<Enum: ConstTryFromPrimitive> ::std::error::Error for ConstTryFromPrimitiveError<Enum> {}
126+
88127
// This trait exists to try to give a more clear error message when someone attempts to derive both FromPrimitive and TryFromPrimitive.
89128
// This isn't allowed because both end up creating a `TryFrom<primitive>` implementation.
90129
// TryFromPrimitive explicitly implements TryFrom<primitive> with Error=TryFromPrimitiveError, which conflicts with:
@@ -94,3 +133,7 @@ impl<Enum: TryFromPrimitive> ::std::error::Error for TryFromPrimitiveError<Enum>
94133
// It is subject to change in any release regardless of semver.
95134
#[doc(hidden)]
96135
pub trait CannotDeriveBothFromPrimitiveAndTryFromPrimitive {}
136+
137+
// Similar, for const primitive coercion methods.
138+
#[doc(hidden)]
139+
pub trait CannotDeriveBothConstFromPrimitiveAndConstTryFromPrimitive {}

0 commit comments

Comments
 (0)