ckb_occupied_capacity_core/
units.rs1use serde::{Deserialize, Serialize};
2
3#[derive(
7 Debug, Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize,
8)]
9pub struct Capacity(u64);
10
11#[derive(Clone, PartialEq, Debug, Eq, Copy, Deserialize, Serialize)]
14pub struct Ratio {
15 numer: u64,
17 denom: u64,
19}
20
21impl Ratio {
22 pub const fn new(numer: u64, denom: u64) -> Self {
24 Self { numer, denom }
25 }
26
27 pub fn numer(&self) -> u64 {
29 self.numer
30 }
31
32 pub fn denom(&self) -> u64 {
34 self.denom
35 }
36}
37
38pub trait IntoCapacity {
40 fn into_capacity(self) -> Capacity;
42}
43
44impl IntoCapacity for Capacity {
45 fn into_capacity(self) -> Capacity {
46 self
47 }
48}
49
50impl IntoCapacity for u64 {
51 fn into_capacity(self) -> Capacity {
52 Capacity::shannons(self)
53 }
54}
55
56impl IntoCapacity for u32 {
57 fn into_capacity(self) -> Capacity {
58 Capacity::shannons(u64::from(self))
59 }
60}
61
62impl IntoCapacity for u16 {
63 fn into_capacity(self) -> Capacity {
64 Capacity::shannons(u64::from(self))
65 }
66}
67
68impl IntoCapacity for u8 {
69 fn into_capacity(self) -> Capacity {
70 Capacity::shannons(u64::from(self))
71 }
72}
73
74const BYTE_SHANNONS: u64 = 100_000_000;
76
77#[derive(Debug, Clone, PartialEq, Eq)]
79pub enum Error {
80 Overflow,
82}
83
84impl ::std::fmt::Display for Error {
85 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
86 write!(f, "OccupiedCapacity: overflow")
87 }
88}
89
90impl ::std::error::Error for Error {}
91
92pub type Result<T> = ::std::result::Result<T, Error>;
94
95impl Capacity {
96 pub const fn zero() -> Self {
98 Capacity(0)
99 }
100
101 pub const fn one() -> Self {
103 Capacity(1)
104 }
105
106 pub const fn shannons(val: u64) -> Self {
108 Capacity(val)
109 }
110
111 pub fn bytes(val: usize) -> Result<Self> {
113 (val as u64)
114 .checked_mul(BYTE_SHANNONS)
115 .map(Capacity::shannons)
116 .ok_or(Error::Overflow)
117 }
118
119 pub fn as_u64(self) -> u64 {
121 self.0
122 }
123
124 pub fn safe_add<C: IntoCapacity>(self, rhs: C) -> Result<Self> {
126 self.0
127 .checked_add(rhs.into_capacity().0)
128 .map(Capacity::shannons)
129 .ok_or(Error::Overflow)
130 }
131
132 pub fn safe_sub<C: IntoCapacity>(self, rhs: C) -> Result<Self> {
134 self.0
135 .checked_sub(rhs.into_capacity().0)
136 .map(Capacity::shannons)
137 .ok_or(Error::Overflow)
138 }
139
140 pub fn safe_mul<C: IntoCapacity>(self, rhs: C) -> Result<Self> {
142 self.0
143 .checked_mul(rhs.into_capacity().0)
144 .map(Capacity::shannons)
145 .ok_or(Error::Overflow)
146 }
147
148 pub fn safe_mul_ratio(self, ratio: Ratio) -> Result<Self> {
150 self.0
151 .checked_mul(ratio.numer())
152 .and_then(|ret| ret.checked_div(ratio.denom()))
153 .map(Capacity::shannons)
154 .ok_or(Error::Overflow)
155 }
156}
157
158impl ::std::str::FromStr for Capacity {
159 type Err = ::std::num::ParseIntError;
160
161 fn from_str(s: &str) -> ::std::result::Result<Self, Self::Err> {
162 Ok(Capacity(s.parse::<u64>()?))
163 }
164}
165
166impl ::std::fmt::Display for Capacity {
167 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
168 self.0.fmt(f)
169 }
170}
171
172impl ::std::fmt::LowerHex for Capacity {
173 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
174 self.0.fmt(f)
175 }
176}