foundry_block_explorers/
block_number.rs1use alloy_primitives::U64;
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3use std::{fmt, str::FromStr};
4
5#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
7pub enum BlockNumber {
8 #[default]
10 Latest,
11 Finalized,
13 Safe,
15 Earliest,
17 Pending,
19 Number(U64),
21}
22
23impl BlockNumber {
24 pub fn as_number(&self) -> Option<U64> {
26 match *self {
27 BlockNumber::Number(num) => Some(num),
28 _ => None,
29 }
30 }
31
32 pub fn is_number(&self) -> bool {
34 matches!(self, BlockNumber::Number(_))
35 }
36
37 pub fn is_latest(&self) -> bool {
39 matches!(self, BlockNumber::Latest)
40 }
41
42 pub fn is_finalized(&self) -> bool {
44 matches!(self, BlockNumber::Finalized)
45 }
46
47 pub fn is_safe(&self) -> bool {
49 matches!(self, BlockNumber::Safe)
50 }
51
52 pub fn is_pending(&self) -> bool {
54 matches!(self, BlockNumber::Pending)
55 }
56
57 pub fn is_earliest(&self) -> bool {
59 matches!(self, BlockNumber::Earliest)
60 }
61}
62
63impl<T: Into<U64>> From<T> for BlockNumber {
64 fn from(num: T) -> Self {
65 BlockNumber::Number(num.into())
66 }
67}
68
69impl Serialize for BlockNumber {
70 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
71 where
72 S: Serializer,
73 {
74 match *self {
75 BlockNumber::Number(ref x) => serializer.serialize_str(&format!("0x{x:x}")),
76 BlockNumber::Latest => serializer.serialize_str("latest"),
77 BlockNumber::Finalized => serializer.serialize_str("finalized"),
78 BlockNumber::Safe => serializer.serialize_str("safe"),
79 BlockNumber::Earliest => serializer.serialize_str("earliest"),
80 BlockNumber::Pending => serializer.serialize_str("pending"),
81 }
82 }
83}
84
85impl<'de> Deserialize<'de> for BlockNumber {
86 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
87 where
88 D: Deserializer<'de>,
89 {
90 let s = String::deserialize(deserializer)?.to_lowercase();
91 s.parse().map_err(serde::de::Error::custom)
92 }
93}
94
95impl FromStr for BlockNumber {
96 type Err = String;
97
98 fn from_str(s: &str) -> Result<Self, Self::Err> {
99 match s {
100 "latest" => Ok(Self::Latest),
101 "finalized" => Ok(Self::Finalized),
102 "safe" => Ok(Self::Safe),
103 "earliest" => Ok(Self::Earliest),
104 "pending" => Ok(Self::Pending),
105 n if n.starts_with("0x") => n.parse().map(Self::Number).map_err(|e| e.to_string()),
107 n => n.parse::<u64>().map(|n| Self::Number(U64::from(n))).map_err(|e| e.to_string()),
109 }
110 }
111}
112
113impl fmt::Display for BlockNumber {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 match self {
116 BlockNumber::Number(ref x) => format!("0x{x:x}").fmt(f),
117 BlockNumber::Latest => f.write_str("latest"),
118 BlockNumber::Finalized => f.write_str("finalized"),
119 BlockNumber::Safe => f.write_str("safe"),
120 BlockNumber::Earliest => f.write_str("earliest"),
121 BlockNumber::Pending => f.write_str("pending"),
122 }
123 }
124}