feophantlib/engine/transactions/
transaction_id.rs

1//! A simple wrapper around a primitive so I can play with transaction id sizes.
2use std::convert::TryFrom;
3use std::fmt;
4use std::num::TryFromIntError;
5use thiserror::Error;
6
7use crate::engine::io::ConstEncodedSize;
8
9#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
10pub struct TransactionId(u64);
11
12impl TransactionId {
13    pub fn new(value: u64) -> TransactionId {
14        TransactionId(value)
15    }
16
17    pub fn get_u64(&self) -> u64 {
18        self.0
19    }
20
21    pub fn checked_add(self, rhs: usize) -> Result<TransactionId, TransactionIdError> {
22        let rhs_u64 = u64::try_from(rhs)?;
23        match self.0.checked_add(rhs_u64) {
24            Some(s) => Ok(TransactionId::new(s)),
25            None => Err(TransactionIdError::LimitReached()),
26        }
27    }
28
29    pub fn checked_sub(self, rhs: TransactionId) -> Result<usize, TransactionIdError> {
30        match self.0.checked_sub(rhs.get_u64()) {
31            Some(s) => Ok(usize::try_from(s)?),
32            None => Err(TransactionIdError::Underflow(self, rhs)),
33        }
34    }
35}
36
37impl ConstEncodedSize for TransactionId {
38    fn encoded_size() -> usize {
39        8
40    }
41}
42
43impl fmt::Display for TransactionId {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        write!(f, "{}", self.0)
46    }
47}
48
49#[derive(Error, Debug)]
50pub enum TransactionIdError {
51    #[error("Unable to convert usize to u64")]
52    ConversionError(#[from] TryFromIntError),
53    #[error("Underflow on subtraction left: {0} right: {1}")]
54    Underflow(TransactionId, TransactionId),
55    #[error("Exceeded counter limit, at the moment your only option is reimporting the database.")]
56    LimitReached(),
57}