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