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}