eva_asm/instruction/
logging.rs

1//! Logging operations.
2
3use derive_more::Display;
4
5use super::Instruction;
6use crate::opcode::{Mnemonic, OpCode};
7
8/// Append log record.
9/// The `N` constant signifies the type of the `LOG` opcode (e.g. `Log<3>` => `LOG3`).
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Display)]
11#[display("{}", self.opcode())]
12pub struct Log<const N: u8> {
13    /// Private field to disallow struct creation outside of this module.
14    _private: (),
15}
16
17impl<const N: u8> Log<N> {
18    /// Compile time assertion to check if `N` is correct.
19    const VALID: () = assert!(N <= 4, "invalid LOG instruction");
20
21    /// Create a new `LOG` instruction with the specified type.
22    ///
23    /// # Example
24    /// ```
25    /// # use eva_asm::instruction::Log;
26    /// let log: Log<4> = Log::new();
27    /// ```
28    ///
29    /// This will fail to compile if the instruction is not correct.
30    ///
31    /// ```compile_fail
32    /// # use eva_asm::instruction::Log;
33    /// let log: Log<10> = Log::new(); // compile fail!
34    /// ```
35    #[must_use]
36    pub const fn new() -> Self {
37        () = Self::VALID;
38        Self { _private: () }
39    }
40}
41
42impl<const N: u8> Default for Log<N> {
43    fn default() -> Self {
44        Self::new()
45    }
46}
47
48impl<const N: u8> Instruction for Log<N> {
49    fn opcode(&self) -> OpCode {
50        match N {
51            0 => OpCode::Known(Mnemonic::LOG0),
52            1 => OpCode::Known(Mnemonic::LOG1),
53            2 => OpCode::Known(Mnemonic::LOG2),
54            3 => OpCode::Known(Mnemonic::LOG3),
55            4 => OpCode::Known(Mnemonic::LOG4),
56            _ => unreachable!(),
57        }
58    }
59}