clack_common/events/spaces/id.rs
1use crate::events::EventSpace;
2use crate::events::spaces::core::CoreEventSpace;
3use clap_sys::events::CLAP_CORE_EVENT_SPACE_ID;
4use std::marker::PhantomData;
5
6/// An event space identifier, optionally tied to its [`EventSpace`] type `S`.
7///
8/// If `S` is the unit type `()`, then this means this identifier is not tied to any particular
9/// event space (i.e. it is type-erased).
10#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
11pub struct EventSpaceId<S = ()> {
12 id: u16,
13 _space: PhantomData<S>,
14}
15
16impl<S> EventSpaceId<S> {
17 /// The raw numeric value that represents an invalid event space identifier.
18 pub const INVALID_ID: u16 = u16::MAX;
19
20 /// Returns raw numeric value of this identifier.
21 ///
22 /// The returned value cannot be equal to [`Self::INVALID_ID`].
23 #[inline]
24 pub const fn id(&self) -> u16 {
25 self.id
26 }
27
28 /// Returns the raw numeric value of the given identifier, or [`Self::INVALID_ID`] if the
29 /// `None` is passed.
30 #[inline]
31 pub const fn optional_id(this: &Option<Self>) -> u16 {
32 match this {
33 Some(i) => i.id,
34 None => u16::MAX,
35 }
36 }
37
38 /// Gets an event space ID from a numerical value, without performing any checks.
39 ///
40 /// # Safety
41 ///
42 /// The caller *must* ensure the event type is properly associated to the event space `S`.
43 /// The caller must also ensure the ID is not equal to [`Self::INVALID_ID`].
44 #[inline]
45 pub const unsafe fn new_unchecked(id: u16) -> Self {
46 Self {
47 id,
48 _space: PhantomData,
49 }
50 }
51}
52
53impl<'a, S: EventSpace<'a>> From<EventSpaceId<S>> for EventSpaceId<()> {
54 #[inline]
55 fn from(id: EventSpaceId<S>) -> Self {
56 Self {
57 id: id.id,
58 _space: PhantomData,
59 }
60 }
61}
62
63impl EventSpaceId<CoreEventSpace<'_>> {
64 /// Returns the identifier for the [`CoreEventSpace`].
65 ///
66 /// It is the only event space that has a constant, specific ID designated by the CLAP
67 /// specification, and which can be retrieved without using an event registry.
68 #[inline]
69 pub const fn core() -> Self {
70 Self {
71 id: CLAP_CORE_EVENT_SPACE_ID,
72 _space: PhantomData,
73 }
74 }
75}
76
77impl EventSpaceId<()> {
78 /// Creates a new, type-erased [`EventSpaceId`] from its raw numeric value.
79 ///
80 /// This returns `None` if the passed value is equal to [`Self::INVALID_ID`].
81 #[inline]
82 pub const fn new(id: u16) -> Option<Self> {
83 if id == u16::MAX {
84 None
85 } else {
86 Some(Self {
87 id,
88 _space: PhantomData,
89 })
90 }
91 }
92
93 /// Turns this unassociated event space ID into one associated with the given event space.
94 ///
95 /// # Safety
96 ///
97 /// The caller *must* ensure the event type is properly associated to the event space `S`.
98 #[inline]
99 pub const unsafe fn into_unchecked<S>(self) -> EventSpaceId<S> {
100 EventSpaceId::new_unchecked(self.id)
101 }
102}