cardano_sdk/cardano/
execution_units.rs

1//  This Source Code Form is subject to the terms of the Mozilla Public
2//  License, v. 2.0. If a copy of the MPL was not distributed with this
3//  file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use crate::{cbor, pallas};
6use std::{cmp::Ordering, fmt};
7
8/// Abstract execution units used to measure execution of [`PlutusScript`](crate::PlutusScript).
9#[derive(Debug, Clone, Copy, PartialEq, Eq, cbor::Encode, cbor::Decode)]
10#[repr(transparent)]
11#[cbor(transparent)]
12pub struct ExecutionUnits(#[n(0)] pallas::ExUnits);
13
14impl fmt::Display for ExecutionUnits {
15    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16        f.debug_struct("ExecutionUnits")
17            .field("mem", &self.mem())
18            .field("cpu", &self.cpu())
19            .finish()
20    }
21}
22
23impl PartialOrd for ExecutionUnits {
24    fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
25        Some(self.cmp(rhs))
26    }
27}
28
29impl Ord for ExecutionUnits {
30    fn cmp(&self, rhs: &Self) -> Ordering {
31        match self.mem().cmp(&rhs.mem()) {
32            Ordering::Equal => self.cpu().cmp(&rhs.cpu()),
33            ordering @ Ordering::Less | ordering @ Ordering::Greater => ordering,
34        }
35    }
36}
37
38// ------------------------------------------------------------------ Inspecting
39
40impl ExecutionUnits {
41    pub fn mem(&self) -> u64 {
42        self.0.mem
43    }
44
45    pub fn cpu(&self) -> u64 {
46        self.0.steps
47    }
48}
49
50// -------------------------------------------------------------------- Building
51
52impl Default for ExecutionUnits {
53    fn default() -> Self {
54        Self(pallas::ExUnits { mem: 0, steps: 0 })
55    }
56}
57
58impl ExecutionUnits {
59    pub fn new(mem: u64, cpu: u64) -> Self {
60        Self(pallas::ExUnits { mem, steps: cpu })
61    }
62}
63
64// ----------------------------------------------------------- Converting (from)
65
66impl From<pallas::ExUnits> for ExecutionUnits {
67    fn from(ex_units: pallas::ExUnits) -> Self {
68        Self(ex_units)
69    }
70}
71
72// ------------------------------------------------------------- Converting (to)
73
74impl From<ExecutionUnits> for pallas::ExUnits {
75    fn from(ex_units: ExecutionUnits) -> Self {
76        ex_units.0
77    }
78}
79
80#[cfg(any(test, feature = "test-utils"))]
81pub mod tests {
82    use crate::{ExecutionUnits, any, pallas};
83    use proptest::prelude::*;
84
85    // -------------------------------------------------------------- Unit tests
86
87    #[test]
88    fn display_execution_units() {
89        assert_eq!(
90            ExecutionUnits::default().to_string(),
91            "ExecutionUnits { mem: 0, cpu: 0 }",
92        );
93    }
94
95    // -------------------------------------------------------------- Properties
96
97    proptest! {
98        #[test]
99        fn pallas_roundtrip(execution_units in any::execution_units()) {
100            let pallas_execution_units = pallas::ExUnits::from(execution_units);
101            let execution_units_back = ExecutionUnits::from(pallas_execution_units);
102            prop_assert_eq!(execution_units, execution_units_back);
103        }
104    }
105
106    // -------------------------------------------------------------- Generators
107
108    pub mod generators {
109        use super::*;
110
111        prop_compose! {
112            pub fn execution_units()(mem in any::<u64>(), cpu in any::<u64>()) -> ExecutionUnits {
113                ExecutionUnits::new(mem, cpu)
114            }
115        }
116    }
117}