tendermint/vote/
validator_index.rs

1use core::{
2    fmt::{self, Debug, Display},
3    str::FromStr,
4};
5
6use crate::{error::Error, prelude::*};
7
8/// ValidatorIndex for a particular Vote
9#[derive(Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
10pub struct ValidatorIndex(u32);
11
12impl TryFrom<i32> for ValidatorIndex {
13    type Error = Error;
14
15    fn try_from(value: i32) -> Result<Self, Self::Error> {
16        Ok(ValidatorIndex(
17            value.try_into().map_err(Error::negative_validator_index)?,
18        ))
19    }
20}
21
22impl From<ValidatorIndex> for i32 {
23    fn from(value: ValidatorIndex) -> Self {
24        value.value() as i32 // does not overflow. The value is <= i32::MAX
25    }
26}
27
28impl TryFrom<u32> for ValidatorIndex {
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        Ok(ValidatorIndex(value))
34    }
35}
36
37impl From<ValidatorIndex> for u32 {
38    fn from(value: ValidatorIndex) -> Self {
39        value.value()
40    }
41}
42
43impl TryFrom<usize> for ValidatorIndex {
44    type Error = Error;
45
46    fn try_from(value: usize) -> Result<Self, Self::Error> {
47        // Convert to i32 first to perform ≤ i32::MAX check.
48        let value = i32::try_from(value).map_err(Error::integer_overflow)?;
49        ValidatorIndex::try_from(value)
50    }
51}
52
53impl From<ValidatorIndex> for usize {
54    fn from(value: ValidatorIndex) -> Self {
55        value
56            .value()
57            .try_into()
58            .expect("Integer overflow: system usize maximum smaller than i32 maximum")
59    }
60}
61
62impl ValidatorIndex {
63    /// Get inner integer value. Alternative to `.0` or `.into()`
64    pub fn value(&self) -> u32 {
65        self.0
66    }
67}
68
69impl Debug for ValidatorIndex {
70    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71        write!(f, "vote::ValidatorIndex({})", self.0)
72    }
73}
74
75impl Display for ValidatorIndex {
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        write!(f, "{}", self.0)
78    }
79}
80
81impl FromStr for ValidatorIndex {
82    type Err = Error;
83
84    fn from_str(s: &str) -> Result<Self, Error> {
85        ValidatorIndex::try_from(
86            s.parse::<u32>()
87                .map_err(|e| Error::parse_int("validator index decode".to_string(), e))?,
88        )
89    }
90}
91
92#[test]
93fn test_i32_max_limit() {
94    assert!(ValidatorIndex::try_from(u32::MAX).is_err());
95    assert!(ValidatorIndex::try_from(u32::MAX as usize).is_err());
96    let value = u32::MAX.to_string();
97    assert!(ValidatorIndex::from_str(&value).is_err());
98}