Skip to main content

amaru_kernel/cardano/
slot.rs

1// Copyright 2026 PRAGMA
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::{fmt, ops::Add};
16
17use minicbor::{Decode, Decoder, Encode};
18
19#[derive(Clone, Debug, Copy, PartialEq, PartialOrd, Ord, Eq, Hash, serde::Serialize, serde::Deserialize, Default)]
20#[repr(transparent)]
21pub struct Slot(u64);
22
23impl fmt::Display for Slot {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        write!(f, "{}", self.0)
26    }
27}
28
29#[derive(Debug, PartialEq, Eq, thiserror::Error, serde::Serialize, serde::Deserialize)]
30pub enum SlotArithmeticError {
31    #[error("slot arithmetic underflow, subtracting {1} from {0}")]
32    Underflow(u64, u64),
33}
34
35impl Slot {
36    pub fn new(slot: u64) -> Self {
37        Self(slot)
38    }
39
40    pub fn elapsed_from(&self, slot: Slot) -> Result<u64, SlotArithmeticError> {
41        if self.0 < slot.0 {
42            return Err(SlotArithmeticError::Underflow(self.0, slot.0));
43        }
44        Ok(self.0 - slot.0)
45    }
46
47    pub fn offset_by(&self, slots_elapsed: u64) -> Slot {
48        Slot(self.0 + slots_elapsed)
49    }
50
51    pub fn as_u64(&self) -> u64 {
52        self.0
53    }
54}
55
56impl From<u64> for Slot {
57    fn from(slot: u64) -> Slot {
58        Slot(slot)
59    }
60}
61
62impl From<Slot> for u64 {
63    fn from(slot: Slot) -> u64 {
64        slot.0
65    }
66}
67
68impl Add<u64> for Slot {
69    type Output = Self;
70
71    fn add(self, rhs: u64) -> Self::Output {
72        Slot(self.0 + rhs)
73    }
74}
75
76impl<C> Encode<C> for Slot {
77    fn encode<W: minicbor::encode::Write>(
78        &self,
79        e: &mut minicbor::Encoder<W>,
80        ctx: &mut C,
81    ) -> Result<(), minicbor::encode::Error<W::Error>> {
82        self.0.encode(e, ctx)
83    }
84}
85
86impl<'b, C> Decode<'b, C> for Slot {
87    fn decode(d: &mut Decoder<'b>, _ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
88        d.u64().map(Slot)
89    }
90}