Skip to main content

airbender_core/
guest.rs

1//! Guest-side output commitment traits shared between host and guest crates.
2
3/// Values that can be committed to the public output registers (`x10..x17`).
4pub trait Commit {
5    fn commit_words(&self) -> [u32; 8];
6}
7
8impl Commit for () {
9    fn commit_words(&self) -> [u32; 8] {
10        [0u32; 8]
11    }
12}
13
14impl Commit for u32 {
15    fn commit_words(&self) -> [u32; 8] {
16        let mut words = [0u32; 8];
17        words[0] = *self;
18        words
19    }
20}
21
22impl Commit for u64 {
23    fn commit_words(&self) -> [u32; 8] {
24        let mut words = [0u32; 8];
25        words[0] = *self as u32;
26        words[1] = (*self >> 32) as u32;
27        words
28    }
29}
30
31impl Commit for i64 {
32    fn commit_words(&self) -> [u32; 8] {
33        (*self as u64).commit_words()
34    }
35}
36
37impl Commit for bool {
38    fn commit_words(&self) -> [u32; 8] {
39        let mut words = [0u32; 8];
40        words[0] = u32::from(*self);
41        words
42    }
43}
44
45impl Commit for [u32; 8] {
46    fn commit_words(&self) -> [u32; 8] {
47        *self
48    }
49}
50
51impl<T: Commit, E: core::fmt::Debug> Commit for Result<T, E> {
52    fn commit_words(&self) -> [u32; 8] {
53        match self {
54            Ok(val) => val.commit_words(),
55            Err(e) => panic!("committed a Result::Err: {:?}", e),
56        }
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn commit_words_u64_layout() {
66        let value: u64 = 0x11223344_55667788;
67        let words = <u64 as Commit>::commit_words(&value);
68        assert_eq!(words[0], 0x55667788);
69        assert_eq!(words[1], 0x11223344);
70        assert_eq!(words[2], 0);
71    }
72
73    #[test]
74    fn commit_words_bool_layout() {
75        let words = <bool as Commit>::commit_words(&true);
76        assert_eq!(words[0], 1);
77        let words = <bool as Commit>::commit_words(&false);
78        assert_eq!(words[0], 0);
79    }
80
81    #[test]
82    fn commit_words_result_ok() {
83        let result: Result<u32, &str> = Ok(42);
84        let words = result.commit_words();
85        assert_eq!(words[0], 42);
86        assert_eq!(words[1], 0);
87    }
88
89    #[test]
90    #[should_panic(expected = "committed a Result::Err")]
91    fn commit_words_result_err_panics() {
92        let result: Result<u32, &str> = Err("something went wrong");
93        result.commit_words();
94    }
95}