amaru_kernel/cardano/
era_bound.rs1use std::time::Duration;
16
17use crate::{Epoch, Slot, cbor, utils::cbor::SerialisedAsPico};
18
19#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
20pub struct EraBound {
21 #[serde(deserialize_with = "SerialisedAsPico::deserialize")]
22 #[serde(serialize_with = "SerialisedAsPico::serialize")]
23 pub time: Duration,
24 pub slot: Slot,
25 pub epoch: Epoch,
26}
27
28impl<C> cbor::Encode<C> for EraBound {
29 fn encode<W: cbor::encode::Write>(
30 &self,
31 e: &mut cbor::Encoder<W>,
32 ctx: &mut C,
33 ) -> Result<(), cbor::encode::Error<W::Error>> {
34 e.array(3)?;
35 SerialisedAsPico::from(self.time).encode(e, ctx)?;
36 self.slot.encode(e, ctx)?;
37 self.epoch.encode(e, ctx)?;
38 Ok(())
39 }
40}
41
42impl<'b, C> cbor::Decode<'b, C> for EraBound {
43 fn decode(d: &mut cbor::Decoder<'b>, ctx: &mut C) -> Result<Self, cbor::decode::Error> {
44 cbor::heterogeneous_array(d, |d, assert_len| {
45 assert_len(3)?;
46 let time = From::<SerialisedAsPico>::from(d.decode()?);
47 let slot = d.decode()?;
48 let epoch = d.decode_with(ctx)?;
49 Ok(EraBound { time, slot, epoch })
50 })
51 }
52}
53
54#[cfg(any(test, feature = "test-utils"))]
55pub use tests::*;
56
57#[cfg(any(test, feature = "test-utils"))]
58mod tests {
59 use proptest::prelude::*;
60
61 use super::*;
62 use crate::prop_cbor_roundtrip;
63
64 prop_compose! {
65 pub fn any_era_bound_time()(secs in any::<u32>()) -> Duration {
66 Duration::from_secs(secs as u64)
67 }
68 }
69
70 prop_compose! {
71 pub fn any_era_bound()(time in any_era_bound_time(), slot in any::<u32>(), epoch in any::<Epoch>()) -> EraBound {
72 EraBound {
73 time, slot: Slot::new(slot as u64), epoch
74 }
75 }
76 }
77
78 prop_compose! {
79 pub fn any_era_bound_for_epoch(epoch: Epoch)(time in any_era_bound_time(), slot in any::<u32>()) -> EraBound {
80 EraBound {
81 time, slot: Slot::new(slot as u64), epoch
82 }
83 }
84 }
85
86 prop_cbor_roundtrip!(EraBound, any_era_bound());
87}