casper_node/components/consensus/utils/
weight.rs

1use std::{
2    iter::Sum,
3    ops::{Div, Mul},
4};
5
6use datasize::DataSize;
7use derive_more::{Add, AddAssign, From, Sub, SubAssign, Sum};
8use serde::{Deserialize, Serialize};
9
10/// A vote weight.
11#[derive(
12    Copy,
13    Clone,
14    DataSize,
15    Default,
16    Debug,
17    PartialEq,
18    Eq,
19    PartialOrd,
20    Ord,
21    Add,
22    Serialize,
23    Deserialize,
24    Sub,
25    AddAssign,
26    SubAssign,
27    Sum,
28    From,
29)]
30pub struct Weight(pub u64);
31
32impl Weight {
33    /// Checked addition. Returns `None` if overflow occurred.
34    pub fn checked_add(self, rhs: Weight) -> Option<Weight> {
35        Some(Weight(self.0.checked_add(rhs.0)?))
36    }
37
38    /// Saturating addition. Returns `Weight(u64::MAX)` if overflow would occur.
39    #[allow(dead_code)]
40    pub fn saturating_add(self, rhs: Weight) -> Weight {
41        Weight(self.0.saturating_add(rhs.0))
42    }
43
44    /// Saturating subtraction. Returns `Weight(0)` if underflow would occur.
45    pub fn saturating_sub(self, rhs: Weight) -> Weight {
46        Weight(self.0.saturating_sub(rhs.0))
47    }
48
49    /// Returns `true` if this weight is zero.
50    pub fn is_zero(self) -> bool {
51        self.0 == 0
52    }
53}
54
55impl<'a> Sum<&'a Weight> for Weight {
56    fn sum<I: Iterator<Item = &'a Weight>>(iter: I) -> Self {
57        Weight(iter.map(|w| w.0).sum())
58    }
59}
60
61impl Mul<u64> for Weight {
62    type Output = Self;
63
64    #[allow(clippy::arithmetic_side_effects)] // The caller needs to prevent overflows.
65    fn mul(self, rhs: u64) -> Self {
66        Weight(self.0 * rhs)
67    }
68}
69
70impl Div<u64> for Weight {
71    type Output = Self;
72
73    #[allow(clippy::arithmetic_side_effects)] // The caller needs to avoid dividing by zero.
74    fn div(self, rhs: u64) -> Self {
75        Weight(self.0 / rhs)
76    }
77}
78
79impl From<Weight> for u128 {
80    fn from(Weight(w): Weight) -> u128 {
81        u128::from(w)
82    }
83}