1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
pub use crate::block;
pub use std::{cmp::Ordering, fmt};
#[cfg(feature = "serde")]
use {
crate::serializers,
serde::{Deserialize, Serialize},
};
pub const NIL_PLACEHOLDER: &str = "<nil>";
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct State {
pub height: block::Height,
#[cfg_attr(
feature = "serde",
serde(
serialize_with = "serializers::serialize_i64",
deserialize_with = "serializers::parse_i64"
)
)]
pub round: i64,
pub step: i8,
pub block_id: Option<block::Id>,
}
impl State {
pub fn block_id_prefix(&self) -> String {
self.block_id
.as_ref()
.map(block::Id::prefix)
.unwrap_or_else(|| NIL_PLACEHOLDER.to_owned())
}
}
impl fmt::Display for State {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}/{}/{}", self.height, self.round, self.step)
}
}
impl Ord for State {
fn cmp(&self, other: &State) -> Ordering {
if self.height < other.height {
Ordering::Less
} else if self.height == other.height {
if self.round < other.round {
Ordering::Less
} else if self.round == other.round {
self.step.cmp(&other.step)
} else {
Ordering::Greater
}
} else {
Ordering::Greater
}
}
}
impl PartialOrd for State {
fn partial_cmp(&self, other: &State) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[cfg(test)]
mod tests {
use super::State;
use crate::block;
#[test]
fn state_ord_test() {
let new = State {
height: block::Height::from(9001u64),
round: 0,
step: 0,
block_id: None,
};
let old = State {
height: block::Height::from(1001u64),
round: 1,
step: 0,
block_id: None,
};
let older = State {
height: block::Height::from(1001u64),
round: 0,
step: 0,
block_id: None,
};
let oldest = State {
height: block::Height::default(),
round: 0,
step: 0,
block_id: None,
};
assert!(old < new);
assert!(older < old);
assert!(oldest < older);
assert!(oldest < new);
}
}