1 | // Wrap this in two cfg_attrs so that it continues to parse pre-1.54.0. |
2 | // See https://github.com/rust-lang/rust/issues/82768 |
3 | #![cfg_attr (feature = "external_doc" , cfg_attr(all(), doc = include_str!("../README.md" )))] |
4 | #![cfg_attr ( |
5 | not(feature = "external_doc" ), |
6 | doc = "See <https://docs.rs/num_enum> for more info about this crate." |
7 | )] |
8 | #![cfg_attr (not(feature = "std" ), no_std)] |
9 | |
10 | pub use ::num_enum_derive::{ |
11 | Default, FromPrimitive, IntoPrimitive, TryFromPrimitive, UnsafeFromPrimitive, |
12 | }; |
13 | |
14 | use ::core::fmt; |
15 | |
16 | pub trait FromPrimitive: Sized { |
17 | type Primitive: Copy + Eq; |
18 | |
19 | fn from_primitive(number: Self::Primitive) -> Self; |
20 | } |
21 | |
22 | pub trait TryFromPrimitive: Sized { |
23 | type Primitive: Copy + Eq + fmt::Debug; |
24 | type Error; |
25 | |
26 | const NAME: &'static str; |
27 | |
28 | fn try_from_primitive(number: Self::Primitive) -> Result<Self, Self::Error>; |
29 | } |
30 | |
31 | pub trait UnsafeFromPrimitive: Sized { |
32 | type Primitive: Copy + Eq; |
33 | |
34 | /// Transmutes into an enum from its primitive. |
35 | /// |
36 | /// # Safety |
37 | /// |
38 | /// - `number` must represent a valid discriminant of `Self`. |
39 | #[deprecated ( |
40 | since = "0.6.0" , |
41 | note = "Prefer to use `unchecked_transmute_from`, `from_unchecked` will be removed in a future release." |
42 | )] |
43 | unsafe fn from_unchecked(number: Self::Primitive) -> Self { |
44 | Self::unchecked_transmute_from(number) |
45 | } |
46 | |
47 | /// Transmutes into an enum from its primitive. |
48 | /// |
49 | /// # Safety |
50 | /// |
51 | /// - `number` must represent a valid discriminant of `Self`. |
52 | unsafe fn unchecked_transmute_from(number: Self::Primitive) -> Self; |
53 | } |
54 | |
55 | #[derive (Copy, Clone, PartialEq, Eq)] |
56 | pub struct TryFromPrimitiveError<Enum: TryFromPrimitive> { |
57 | pub number: Enum::Primitive, |
58 | } |
59 | |
60 | impl<Enum: TryFromPrimitive> TryFromPrimitiveError<Enum> { |
61 | pub fn new(number: Enum::Primitive) -> Self { |
62 | Self { number } |
63 | } |
64 | } |
65 | |
66 | impl<Enum: TryFromPrimitive> fmt::Debug for TryFromPrimitiveError<Enum> { |
67 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
68 | fmt&mut DebugStruct<'_, '_>.debug_struct("TryFromPrimitiveError" ) |
69 | .field(name:"number" , &self.number) |
70 | .finish() |
71 | } |
72 | } |
73 | impl<Enum: TryFromPrimitive> fmt::Display for TryFromPrimitiveError<Enum> { |
74 | fn fmt(&self, stream: &'_ mut fmt::Formatter<'_>) -> fmt::Result { |
75 | write!( |
76 | stream, |
77 | "No discriminant in enum ` {name}` matches the value ` {input:?}`" , |
78 | name = Enum::NAME, |
79 | input = self.number, |
80 | ) |
81 | } |
82 | } |
83 | |
84 | #[cfg (feature = "std" )] |
85 | impl<Enum: TryFromPrimitive> ::std::error::Error for TryFromPrimitiveError<Enum> {} |
86 | |
87 | // This trait exists to try to give a more clear error message when someone attempts to derive both FromPrimitive and TryFromPrimitive. |
88 | // This isn't allowed because both end up creating a `TryFrom<primitive>` implementation. |
89 | // TryFromPrimitive explicitly implements TryFrom<primitive> with Error=TryFromPrimitiveError, which conflicts with: |
90 | // FromPrimitive explicitly implements From<primitive> which has a blanket implementation of TryFrom<primitive> with Error=Infallible. |
91 | // |
92 | // This is a private implementation detail of the num_enum crate which should not be depended on externally. |
93 | // It is subject to change in any release regardless of semver. |
94 | #[doc (hidden)] |
95 | pub trait CannotDeriveBothFromPrimitiveAndTryFromPrimitive {} |
96 | |