miden_core/
event_id.rs

1use core::fmt::{Display, Formatter};
2
3use crate::{Felt, utils::hash_string_to_word};
4
5/// A type-safe wrapper around a [`Felt`] that represents an event identifier.
6///
7/// Event IDs are used to identify events that can be emitted by the VM or handled by the host.
8/// This newtype provides type safety and ensures that event IDs are not accidentally confused
9/// with other [`Felt`] values.
10///
11/// While not enforced by this type, the values 0..256 are reserved for
12/// [`SystemEvent`](crate::sys_events::SystemEvent)s.
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub struct EventId(Felt);
15
16impl EventId {
17    /// Computes the canonical event identifier for the given `name`.
18    ///
19    /// This function provides a stable, deterministic mapping from human-readable event names
20    /// to field elements that can be used as event identifiers in the VM. The mapping works by:
21    /// 1. Computing the BLAKE3 hash of the event name (produces 32 bytes)
22    /// 2. Taking the first 8 bytes of the hash
23    /// 3. Interpreting these bytes as a little-endian u64
24    /// 4. Reducing modulo the field prime to create a valid Felt
25    ///
26    /// Note that this is the same procedure performed by [`hash_string_to_word`], where we take
27    /// the first element of the resulting [`Word`](crate::Word).
28    ///
29    /// This ensures that identical event names always produce the same event ID, while
30    /// providing good distribution properties to minimize collisions between different names.
31    pub fn from_name(name: impl AsRef<str>) -> Self {
32        let digest_word = hash_string_to_word(name.as_ref());
33
34        Self(digest_word[0])
35    }
36
37    /// Creates a new event ID from a [`Felt`].
38    pub const fn from_felt(value: Felt) -> Self {
39        Self(value)
40    }
41
42    /// Creates a new event ID from a u64, converting it to a [`Felt`].
43    pub const fn from_u64(value: u64) -> Self {
44        Self(Felt::new(value))
45    }
46
47    /// Returns the underlying [`Felt`] value.
48    pub const fn as_felt(&self) -> Felt {
49        self.0
50    }
51
52    /// Returns `true` if this event ID is reserved for a
53    /// [`SystemEvent`](crate::sys_events::SystemEvent).
54    pub const fn is_reserved(&self) -> bool {
55        let value = self.0.as_int();
56        value <= u8::MAX as u64
57    }
58}
59
60impl PartialOrd for EventId {
61    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
62        Some(self.cmp(other))
63    }
64}
65
66impl Ord for EventId {
67    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
68        self.0.inner().cmp(&other.0.inner())
69    }
70}
71
72impl Display for EventId {
73    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
74        core::fmt::Display::fmt(&self.0, f)
75    }
76}