data_anchor_client/fees/
lamports.rs1use std::{fmt::Display, num::TryFromIntError};
2
3use thiserror::Error;
4
5use super::MicroLamports;
6
7#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
9pub struct Lamports(pub(crate) u32);
10
11impl Lamports {
12 pub const ZERO: Self = Lamports(0);
14
15 pub fn new(value: u32) -> Self {
17 Lamports(value)
18 }
19
20 pub fn into_inner(self) -> u32 {
22 self.0
23 }
24
25 pub fn checked_mul(&self, rhs: u32) -> Option<Self> {
27 self.0.checked_mul(rhs).map(Lamports)
28 }
29
30 pub fn checked_div(&self, rhs: u32) -> Option<Self> {
32 self.0.checked_div(rhs).map(Lamports)
33 }
34
35 pub fn checked_add(&self, rhs: Self) -> Option<Self> {
37 self.0.checked_add(rhs.0).map(Lamports)
38 }
39
40 pub fn checked_sub(&self, rhs: Self) -> Option<Self> {
42 self.0.checked_sub(rhs.0).map(Lamports)
43 }
44}
45
46impl Display for Lamports {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 write!(f, "{} lamports", self.0)
49 }
50}
51
52impl TryFrom<MicroLamports> for Lamports {
53 type Error = LamportsFromMicroLamportsError;
54
55 fn try_from(value: MicroLamports) -> Result<Self, Self::Error> {
56 Ok(Lamports(value.0.div_ceil(1_000_000).try_into().map_err(
57 |e| LamportsFromMicroLamportsError::Overflow(value.0, e),
58 )?))
59 }
60}
61
62#[derive(Error, Debug, PartialEq, Eq)]
63pub enum LamportsFromMicroLamportsError {
64 #[error(
65 "Microlamports value is too large ({0} / 1 000 000 > 2^32-1), it would overflow ({1})"
66 )]
67 Overflow(u64, #[source] TryFromIntError),
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn micro_lamports_to_lamports_rounds_up() {
76 assert_eq!(Lamports::try_from(MicroLamports(0)), Ok(Lamports(0)));
77 assert_eq!(Lamports::try_from(MicroLamports(500_000)), Ok(Lamports(1)));
78 assert_eq!(
79 Lamports::try_from(MicroLamports(1_000_000)),
80 Ok(Lamports(1))
81 );
82 assert_eq!(
83 Lamports::try_from(MicroLamports(1_000_001)),
84 Ok(Lamports(2))
85 );
86 }
87
88 #[test]
89 fn more_than_max_lamports_errors() {
90 let too_large_value = (u32::MAX as u64 + 1) * 1_000_000;
91 let err = Lamports::try_from(MicroLamports(too_large_value)).unwrap_err();
92 assert_eq!(
93 err.to_string(),
94 "Microlamports value is too large (4294967296000000 / 1 000 000 > 2^32-1), it would overflow (out of range integral type conversion attempted)",
95 );
96 }
97}