iq_cometbft/block/
round.rs1use core::{
2 convert::{TryFrom, TryInto},
3 fmt::{self, Debug, Display},
4 str::FromStr,
5};
6
7use serde::{de::Error as _, Deserialize, Deserializer, Serialize, Serializer};
8
9use crate::{error::Error, prelude::*};
10
11#[derive(Copy, Clone, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
13pub struct Round(u32);
14
15impl TryFrom<i32> for Round {
16 type Error = Error;
17
18 fn try_from(value: i32) -> Result<Self, Self::Error> {
19 Ok(Round(value.try_into().map_err(Error::negative_round)?))
20 }
21}
22
23impl From<Round> for i32 {
24 fn from(value: Round) -> Self {
25 value.value() as i32 }
27}
28
29impl TryFrom<u32> for Round {
30 type Error = Error;
31
32 fn try_from(value: u32) -> Result<Self, Self::Error> {
33 let _val: i32 = value.try_into().map_err(Error::integer_overflow)?;
34
35 Ok(Round(value))
36 }
37}
38
39impl From<Round> for u32 {
40 fn from(value: Round) -> Self {
41 value.value()
42 }
43}
44
45impl From<u16> for Round {
46 fn from(value: u16) -> Self {
47 Round(value as u32)
48 }
49}
50
51impl From<u8> for Round {
52 fn from(value: u8) -> Self {
53 Round(value as u32)
54 }
55}
56
57impl Round {
58 pub fn value(&self) -> u32 {
60 self.0
61 }
62
63 pub fn increment(self) -> Self {
65 Round::try_from(self.0.checked_add(1).expect("round overflow")).unwrap()
66 }
67}
68
69impl Debug for Round {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 write!(f, "block::Round({})", self.0)
72 }
73}
74
75impl Display for Round {
76 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 write!(f, "{}", self.0)
78 }
79}
80
81impl FromStr for Round {
82 type Err = Error;
83
84 fn from_str(s: &str) -> Result<Self, Error> {
85 Round::try_from(
86 s.parse::<u32>()
87 .map_err(|e| Error::parse_int(s.to_string(), e))?,
88 )
89 }
90}
91
92impl<'de> Deserialize<'de> for Round {
93 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
94 Self::from_str(&String::deserialize(deserializer)?)
95 .map_err(|e| D::Error::custom(format!("{e}")))
96 }
97}
98
99impl Serialize for Round {
100 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
101 u32::from(*self).to_string().serialize(serializer)
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn increment_by_one() {
111 assert_eq!(Round::default().increment().value(), 1);
112 }
113
114 #[test]
115 fn avoid_try_unwrap_dance() {
116 assert_eq!(
117 Round::try_from(2_u32).unwrap().value(),
118 Round::from(2_u16).value()
119 );
120 }
121}