tendermint 0.40.4

Tendermint is a high-performance blockchain consensus engine that powers Byzantine fault tolerant applications written in any programming language. This crate provides core types for representing information about Tendermint blockchain networks, including chain information types, secret connections, and remote procedure calls (JSON-RPC).
Documentation
use core::{
    fmt::{self, Debug, Display},
    str::FromStr,
};

use crate::{error::Error, prelude::*};

/// ValidatorIndex for a particular Vote
#[derive(Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub struct ValidatorIndex(u32);

impl TryFrom<i32> for ValidatorIndex {
    type Error = Error;

    fn try_from(value: i32) -> Result<Self, Self::Error> {
        Ok(ValidatorIndex(
            value.try_into().map_err(Error::negative_validator_index)?,
        ))
    }
}

impl From<ValidatorIndex> for i32 {
    fn from(value: ValidatorIndex) -> Self {
        value.value() as i32 // does not overflow. The value is <= i32::MAX
    }
}

impl TryFrom<u32> for ValidatorIndex {
    type Error = Error;

    fn try_from(value: u32) -> Result<Self, Self::Error> {
        let _val: i32 = value.try_into().map_err(Error::integer_overflow)?;
        Ok(ValidatorIndex(value))
    }
}

impl From<ValidatorIndex> for u32 {
    fn from(value: ValidatorIndex) -> Self {
        value.value()
    }
}

impl TryFrom<usize> for ValidatorIndex {
    type Error = Error;

    fn try_from(value: usize) -> Result<Self, Self::Error> {
        // Convert to i32 first to perform ≤ i32::MAX check.
        let value = i32::try_from(value).map_err(Error::integer_overflow)?;
        ValidatorIndex::try_from(value)
    }
}

impl From<ValidatorIndex> for usize {
    fn from(value: ValidatorIndex) -> Self {
        value
            .value()
            .try_into()
            .expect("Integer overflow: system usize maximum smaller than i32 maximum")
    }
}

impl ValidatorIndex {
    /// Get inner integer value. Alternative to `.0` or `.into()`
    pub fn value(&self) -> u32 {
        self.0
    }
}

impl Debug for ValidatorIndex {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "vote::ValidatorIndex({})", self.0)
    }
}

impl Display for ValidatorIndex {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl FromStr for ValidatorIndex {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Error> {
        ValidatorIndex::try_from(
            s.parse::<u32>()
                .map_err(|e| Error::parse_int("validator index decode".to_string(), e))?,
        )
    }
}

#[test]
fn test_i32_max_limit() {
    assert!(ValidatorIndex::try_from(u32::MAX).is_err());
    assert!(ValidatorIndex::try_from(u32::MAX as usize).is_err());
    let value = u32::MAX.to_string();
    assert!(ValidatorIndex::from_str(&value).is_err());
}