1use core::fmt;
8use core::str::FromStr;
9
10#[repr(u8)]
16#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
19pub enum SubstrateKind {
20 Note = 0,
21 Entity = 1,
22 Event = 2,
23}
24
25pub const SUBSTRATE_COUNT: usize = 3;
26
27impl SubstrateKind {
28 pub const ALL: [SubstrateKind; SUBSTRATE_COUNT] = [
29 SubstrateKind::Note,
30 SubstrateKind::Entity,
31 SubstrateKind::Event,
32 ];
33
34 #[inline]
35 pub const fn name(self) -> &'static str {
36 match self {
37 Self::Note => "note",
38 Self::Entity => "entity",
39 Self::Event => "event",
40 }
41 }
42
43 #[inline]
44 pub const fn from_u8(v: u8) -> Option<Self> {
45 match v {
46 0 => Some(Self::Note),
47 1 => Some(Self::Entity),
48 2 => Some(Self::Event),
49 _ => None,
50 }
51 }
52}
53
54impl fmt::Display for SubstrateKind {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 f.write_str(self.name())
57 }
58}
59
60impl FromStr for SubstrateKind {
61 type Err = SubstrateError;
62
63 fn from_str(s: &str) -> Result<Self, Self::Err> {
64 match s {
65 "note" | "Note" => Ok(Self::Note),
66 "entity" | "Entity" => Ok(Self::Entity),
67 "event" | "Event" => Ok(Self::Event),
68 _ => Err(SubstrateError::UnknownKind),
69 }
70 }
71}
72
73#[derive(Clone, Copy, Debug, PartialEq, Eq)]
74pub enum SubstrateError {
75 UnknownKind,
76}
77
78impl fmt::Display for SubstrateError {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 match self {
81 Self::UnknownKind => f.write_str("unknown substrate kind"),
82 }
83 }
84}
85
86#[cfg(feature = "std")]
87impl std::error::Error for SubstrateError {}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn all_variants() {
95 assert_eq!(SubstrateKind::ALL.len(), SUBSTRATE_COUNT);
96 for (i, &kind) in SubstrateKind::ALL.iter().enumerate() {
97 assert_eq!(kind as u8, i as u8);
98 assert_eq!(SubstrateKind::from_u8(i as u8), Some(kind));
99 }
100 }
101
102 #[test]
103 fn parse_roundtrip() {
104 for kind in SubstrateKind::ALL {
105 let parsed: SubstrateKind = kind.name().parse().unwrap();
106 assert_eq!(parsed, kind);
107 }
108 }
109
110 #[test]
111 fn out_of_range() {
112 assert_eq!(SubstrateKind::from_u8(3), None);
113 assert_eq!(SubstrateKind::from_u8(255), None);
114 }
115}