1#![allow(non_camel_case_types)]
2
3use core::str::FromStr;
4pub use SpecId::*;
6
7#[repr(u8)]
11#[derive(
12 Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, enumn::N,
13)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub enum SpecId {
16 FRONTIER = 0, FRONTIER_THAWING, HOMESTEAD, DAO_FORK, TANGERINE, SPURIOUS_DRAGON, BYZANTIUM, CONSTANTINOPLE, PETERSBURG, ISTANBUL, MUIR_GLACIER, BERLIN, LONDON, ARROW_GLACIER, GRAY_GLACIER, MERGE, SHANGHAI, CANCUN, #[default]
37 PRAGUE, OSAKA, }
40
41impl SpecId {
42 #[inline]
44 pub fn try_from_u8(spec_id: u8) -> Option<Self> { Self::n(spec_id) }
45
46 #[inline]
48 pub const fn is_enabled_in(self, other: Self) -> bool {
49 self as u8 >= other as u8
50 }
51}
52
53pub mod name {
55 pub const FRONTIER: &str = "Frontier";
56 pub const FRONTIER_THAWING: &str = "Frontier Thawing";
57 pub const HOMESTEAD: &str = "Homestead";
58 pub const DAO_FORK: &str = "DAO Fork";
59 pub const TANGERINE: &str = "Tangerine";
60 pub const SPURIOUS_DRAGON: &str = "Spurious";
61 pub const BYZANTIUM: &str = "Byzantium";
62 pub const CONSTANTINOPLE: &str = "Constantinople";
63 pub const PETERSBURG: &str = "Petersburg";
64 pub const ISTANBUL: &str = "Istanbul";
65 pub const MUIR_GLACIER: &str = "MuirGlacier";
66 pub const BERLIN: &str = "Berlin";
67 pub const LONDON: &str = "London";
68 pub const ARROW_GLACIER: &str = "Arrow Glacier";
69 pub const GRAY_GLACIER: &str = "Gray Glacier";
70 pub const MERGE: &str = "Merge";
71 pub const SHANGHAI: &str = "Shanghai";
72 pub const CANCUN: &str = "Cancun";
73 pub const PRAGUE: &str = "Prague";
74 pub const OSAKA: &str = "PragueEOF";
75 pub const LATEST: &str = "Latest";
76}
77
78pub struct UnknownHardfork;
79
80impl FromStr for SpecId {
81 type Err = UnknownHardfork;
82
83 fn from_str(s: &str) -> Result<Self, Self::Err> {
84 match s {
85 name::FRONTIER => Ok(Self::FRONTIER),
86 name::FRONTIER_THAWING => Ok(Self::FRONTIER_THAWING),
87 name::HOMESTEAD => Ok(Self::HOMESTEAD),
88 name::DAO_FORK => Ok(Self::DAO_FORK),
89 name::TANGERINE => Ok(Self::TANGERINE),
90 name::SPURIOUS_DRAGON => Ok(Self::SPURIOUS_DRAGON),
91 name::BYZANTIUM => Ok(Self::BYZANTIUM),
92 name::CONSTANTINOPLE => Ok(Self::CONSTANTINOPLE),
93 name::PETERSBURG => Ok(Self::PETERSBURG),
94 name::ISTANBUL => Ok(Self::ISTANBUL),
95 name::MUIR_GLACIER => Ok(Self::MUIR_GLACIER),
96 name::BERLIN => Ok(Self::BERLIN),
97 name::LONDON => Ok(Self::LONDON),
98 name::ARROW_GLACIER => Ok(Self::ARROW_GLACIER),
99 name::GRAY_GLACIER => Ok(Self::GRAY_GLACIER),
100 name::MERGE => Ok(Self::MERGE),
101 name::SHANGHAI => Ok(Self::SHANGHAI),
102 name::CANCUN => Ok(Self::CANCUN),
103 name::PRAGUE => Ok(Self::PRAGUE),
104 name::OSAKA => Ok(Self::OSAKA),
105 _ => Err(UnknownHardfork),
106 }
107 }
108}
109
110impl From<SpecId> for &'static str {
111 fn from(spec_id: SpecId) -> Self {
112 match spec_id {
113 SpecId::FRONTIER => name::FRONTIER,
114 SpecId::FRONTIER_THAWING => name::FRONTIER_THAWING,
115 SpecId::HOMESTEAD => name::HOMESTEAD,
116 SpecId::DAO_FORK => name::DAO_FORK,
117 SpecId::TANGERINE => name::TANGERINE,
118 SpecId::SPURIOUS_DRAGON => name::SPURIOUS_DRAGON,
119 SpecId::BYZANTIUM => name::BYZANTIUM,
120 SpecId::CONSTANTINOPLE => name::CONSTANTINOPLE,
121 SpecId::PETERSBURG => name::PETERSBURG,
122 SpecId::ISTANBUL => name::ISTANBUL,
123 SpecId::MUIR_GLACIER => name::MUIR_GLACIER,
124 SpecId::BERLIN => name::BERLIN,
125 SpecId::LONDON => name::LONDON,
126 SpecId::ARROW_GLACIER => name::ARROW_GLACIER,
127 SpecId::GRAY_GLACIER => name::GRAY_GLACIER,
128 SpecId::MERGE => name::MERGE,
129 SpecId::SHANGHAI => name::SHANGHAI,
130 SpecId::CANCUN => name::CANCUN,
131 SpecId::PRAGUE => name::PRAGUE,
132 SpecId::OSAKA => name::OSAKA,
133 }
134 }
135}
136
137impl core::fmt::Display for SpecId {
138 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
139 write!(f, "{}", <&'static str>::from(*self))
140 }
141}