use core::fmt;
use super::{EventId, EventName};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[repr(u8)]
pub enum SystemEvent {
MerkleNodeMerge,
MerkleNodeToStack,
MapValueToStack,
MapValueCountToStack,
MapValueToStackN0,
MapValueToStackN4,
MapValueToStackN8,
HasMapKey,
Ext2Inv,
U32Clz,
U32Ctz,
U32Clo,
U32Cto,
ILog2,
MemToMap,
HdwordToMap,
HdwordToMapWithDomain,
HqwordToMap,
HpermToMap,
}
impl SystemEvent {
pub const fn from_event_id(event_id: EventId) -> Option<Self> {
let lookup = Self::LOOKUP;
let mut i = 0;
while i < lookup.len() {
if lookup[i].id.as_u64() == event_id.as_u64() {
return Some(lookup[i].event);
}
i += 1;
}
None
}
pub const fn from_name(name: &str) -> Option<Self> {
let lookup = Self::LOOKUP;
let mut i = 0;
while i < lookup.len() {
if str_eq(name, lookup[i].name) {
return Some(lookup[i].event);
}
i += 1;
}
None
}
pub const fn event_name(&self) -> EventName {
EventName::new(Self::LOOKUP[*self as usize].name)
}
pub const fn event_id(&self) -> EventId {
Self::LOOKUP[*self as usize].id
}
pub const fn all() -> [Self; Self::COUNT] {
[
Self::MerkleNodeMerge,
Self::MerkleNodeToStack,
Self::MapValueToStack,
Self::MapValueCountToStack,
Self::MapValueToStackN0,
Self::MapValueToStackN4,
Self::MapValueToStackN8,
Self::HasMapKey,
Self::Ext2Inv,
Self::U32Clz,
Self::U32Ctz,
Self::U32Clo,
Self::U32Cto,
Self::ILog2,
Self::MemToMap,
Self::HdwordToMap,
Self::HdwordToMapWithDomain,
Self::HqwordToMap,
Self::HpermToMap,
]
}
}
impl From<SystemEvent> for EventName {
fn from(system_event: SystemEvent) -> Self {
system_event.event_name()
}
}
impl crate::prettier::PrettyPrint for SystemEvent {
fn render(&self) -> crate::prettier::Document {
crate::prettier::display(self)
}
}
impl fmt::Display for SystemEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
const PREFIX_LEN: usize = "sys::".len();
let (_prefix, rest) = Self::LOOKUP[*self as usize].name.split_at(PREFIX_LEN);
write!(f, "{rest}")
}
}
#[derive(Copy, Clone, Debug)]
pub(crate) struct SystemEventEntry {
pub id: EventId,
pub event: SystemEvent,
pub name: &'static str,
}
impl SystemEvent {
pub const COUNT: usize = 19;
const LOOKUP: [SystemEventEntry; Self::COUNT] = [
SystemEventEntry {
id: EventId::from_u64(7243907139105902342),
event: SystemEvent::MerkleNodeMerge,
name: "sys::merkle_node_merge",
},
SystemEventEntry {
id: EventId::from_u64(6873007751276594108),
event: SystemEvent::MerkleNodeToStack,
name: "sys::merkle_node_to_stack",
},
SystemEventEntry {
id: EventId::from_u64(17843484659000820118),
event: SystemEvent::MapValueToStack,
name: "sys::map_value_to_stack",
},
SystemEventEntry {
id: EventId::from_u64(3470274154276391308),
event: SystemEvent::MapValueCountToStack,
name: "sys::map_value_count_to_stack",
},
SystemEventEntry {
id: EventId::from_u64(11775886982554463322),
event: SystemEvent::MapValueToStackN0,
name: "sys::map_value_to_stack_n_0",
},
SystemEventEntry {
id: EventId::from_u64(3443305460233942990),
event: SystemEvent::MapValueToStackN4,
name: "sys::map_value_to_stack_n_4",
},
SystemEventEntry {
id: EventId::from_u64(1741586542981559489),
event: SystemEvent::MapValueToStackN8,
name: "sys::map_value_to_stack_n_8",
},
SystemEventEntry {
id: EventId::from_u64(5642583036089175977),
event: SystemEvent::HasMapKey,
name: "sys::has_map_key",
},
SystemEventEntry {
id: EventId::from_u64(9660728691489438960),
event: SystemEvent::Ext2Inv,
name: "sys::ext2_inv",
},
SystemEventEntry {
id: EventId::from_u64(1503707361178382932),
event: SystemEvent::U32Clz,
name: "sys::u32_clz",
},
SystemEventEntry {
id: EventId::from_u64(10656887096526143429),
event: SystemEvent::U32Ctz,
name: "sys::u32_ctz",
},
SystemEventEntry {
id: EventId::from_u64(12846584985739176048),
event: SystemEvent::U32Clo,
name: "sys::u32_clo",
},
SystemEventEntry {
id: EventId::from_u64(6773574803673468616),
event: SystemEvent::U32Cto,
name: "sys::u32_cto",
},
SystemEventEntry {
id: EventId::from_u64(7444351342957461231),
event: SystemEvent::ILog2,
name: "sys::ilog2",
},
SystemEventEntry {
id: EventId::from_u64(5768534446586058686),
event: SystemEvent::MemToMap,
name: "sys::mem_to_map",
},
SystemEventEntry {
id: EventId::from_u64(5988159172915333521),
event: SystemEvent::HdwordToMap,
name: "sys::hdword_to_map",
},
SystemEventEntry {
id: EventId::from_u64(6143777601072385586),
event: SystemEvent::HdwordToMapWithDomain,
name: "sys::hdword_to_map_with_domain",
},
SystemEventEntry {
id: EventId::from_u64(11723176702659679401),
event: SystemEvent::HqwordToMap,
name: "sys::hqword_to_map",
},
SystemEventEntry {
id: EventId::from_u64(6190830263511605775),
event: SystemEvent::HpermToMap,
name: "sys::hperm_to_map",
},
];
}
const fn str_eq(a: &str, b: &str) -> bool {
let a_bytes = a.as_bytes();
let b_bytes = b.as_bytes();
if a_bytes.len() != b_bytes.len() {
return false;
}
let mut i = 0;
while i < a_bytes.len() {
if a_bytes[i] != b_bytes[i] {
return false;
}
i += 1;
}
true
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_system_events() {
assert_eq!(SystemEvent::all().len(), SystemEvent::COUNT);
assert_eq!(SystemEvent::LOOKUP.len(), SystemEvent::COUNT);
for (i, (event, entry)) in
SystemEvent::all().iter().zip(SystemEvent::LOOKUP.iter()).enumerate()
{
assert_eq!(
entry.event, *event,
"LOOKUP[{}].event ({:?}) doesn't match all()[{}] ({:?})",
i, entry.event, i, event
);
let computed_id = event.event_id();
assert_eq!(
entry.id,
computed_id,
"LOOKUP[{}].id is EventId::from_u64({}), but {:?}.to_event_id() returns EventId::from_u64({})",
i,
entry.id.as_u64(),
event,
computed_id.as_u64()
);
assert!(
entry.name.starts_with("sys::"),
"SystemEvent name should start with 'sys::': {}",
entry.name
);
let looked_up =
SystemEvent::from_event_id(entry.id).expect("SystemEvent should be found by ID");
assert_eq!(looked_up, *event);
let looked_up_by_name =
SystemEvent::from_name(entry.name).expect("SystemEvent should be found by name");
assert_eq!(looked_up_by_name, *event);
let event_name = event.event_name();
assert_eq!(event_name.as_str(), entry.name);
assert!(SystemEvent::from_name(event_name.as_str()).is_some());
let event_name_from_into: EventName = (*event).into();
assert_eq!(event_name_from_into.as_str(), entry.name);
assert!(SystemEvent::from_name(event_name_from_into.as_str()).is_some());
match event {
SystemEvent::MerkleNodeMerge
| SystemEvent::MerkleNodeToStack
| SystemEvent::MapValueToStack
| SystemEvent::MapValueCountToStack
| SystemEvent::MapValueToStackN0
| SystemEvent::MapValueToStackN4
| SystemEvent::MapValueToStackN8
| SystemEvent::HasMapKey
| SystemEvent::Ext2Inv
| SystemEvent::U32Clz
| SystemEvent::U32Ctz
| SystemEvent::U32Clo
| SystemEvent::U32Cto
| SystemEvent::ILog2
| SystemEvent::MemToMap
| SystemEvent::HdwordToMap
| SystemEvent::HdwordToMapWithDomain
| SystemEvent::HqwordToMap
| SystemEvent::HpermToMap => {},
}
}
}
}