xref: /aosp_15_r20/external/crosvm/base/src/wait_context.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2020 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker use std::time::Duration;
6*bb4ee6a4SAndroid Build Coastguard Worker 
7*bb4ee6a4SAndroid Build Coastguard Worker pub use base_event_token_derive::*;
8*bb4ee6a4SAndroid Build Coastguard Worker use smallvec::SmallVec;
9*bb4ee6a4SAndroid Build Coastguard Worker 
10*bb4ee6a4SAndroid Build Coastguard Worker use crate::descriptor::AsRawDescriptor;
11*bb4ee6a4SAndroid Build Coastguard Worker use crate::platform::EventContext;
12*bb4ee6a4SAndroid Build Coastguard Worker use crate::RawDescriptor;
13*bb4ee6a4SAndroid Build Coastguard Worker use crate::Result;
14*bb4ee6a4SAndroid Build Coastguard Worker 
15*bb4ee6a4SAndroid Build Coastguard Worker /// Trait that can be used to associate events with arbitrary enums when using
16*bb4ee6a4SAndroid Build Coastguard Worker /// `WaitContext`.
17*bb4ee6a4SAndroid Build Coastguard Worker ///
18*bb4ee6a4SAndroid Build Coastguard Worker /// Simple enums that have no or primitive variant data data can use the `#[derive(EventToken)]`
19*bb4ee6a4SAndroid Build Coastguard Worker /// custom derive to implement this trait. See
20*bb4ee6a4SAndroid Build Coastguard Worker /// [event_token_derive::event_token](../base_event_token_derive/fn.event_token.html) for details.
21*bb4ee6a4SAndroid Build Coastguard Worker pub trait EventToken {
22*bb4ee6a4SAndroid Build Coastguard Worker     /// Converts this token into a u64 that can be turned back into a token via `from_raw_token`.
as_raw_token(&self) -> u6423*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_token(&self) -> u64;
24*bb4ee6a4SAndroid Build Coastguard Worker 
25*bb4ee6a4SAndroid Build Coastguard Worker     /// Converts a raw token as returned from `as_raw_token` back into a token.
26*bb4ee6a4SAndroid Build Coastguard Worker     ///
27*bb4ee6a4SAndroid Build Coastguard Worker     /// It is invalid to give a raw token that was not returned via `as_raw_token` from the same
28*bb4ee6a4SAndroid Build Coastguard Worker     /// `Self`. The implementation can expect that this will never happen as a result of its usage
29*bb4ee6a4SAndroid Build Coastguard Worker     /// in `WaitContext`.
from_raw_token(data: u64) -> Self30*bb4ee6a4SAndroid Build Coastguard Worker     fn from_raw_token(data: u64) -> Self;
31*bb4ee6a4SAndroid Build Coastguard Worker }
32*bb4ee6a4SAndroid Build Coastguard Worker 
33*bb4ee6a4SAndroid Build Coastguard Worker impl EventToken for usize {
as_raw_token(&self) -> u6434*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_token(&self) -> u64 {
35*bb4ee6a4SAndroid Build Coastguard Worker         *self as u64
36*bb4ee6a4SAndroid Build Coastguard Worker     }
37*bb4ee6a4SAndroid Build Coastguard Worker 
from_raw_token(data: u64) -> Self38*bb4ee6a4SAndroid Build Coastguard Worker     fn from_raw_token(data: u64) -> Self {
39*bb4ee6a4SAndroid Build Coastguard Worker         data as Self
40*bb4ee6a4SAndroid Build Coastguard Worker     }
41*bb4ee6a4SAndroid Build Coastguard Worker }
42*bb4ee6a4SAndroid Build Coastguard Worker 
43*bb4ee6a4SAndroid Build Coastguard Worker impl EventToken for u64 {
as_raw_token(&self) -> u6444*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_token(&self) -> u64 {
45*bb4ee6a4SAndroid Build Coastguard Worker         *self
46*bb4ee6a4SAndroid Build Coastguard Worker     }
47*bb4ee6a4SAndroid Build Coastguard Worker 
from_raw_token(data: u64) -> Self48*bb4ee6a4SAndroid Build Coastguard Worker     fn from_raw_token(data: u64) -> Self {
49*bb4ee6a4SAndroid Build Coastguard Worker         data as Self
50*bb4ee6a4SAndroid Build Coastguard Worker     }
51*bb4ee6a4SAndroid Build Coastguard Worker }
52*bb4ee6a4SAndroid Build Coastguard Worker 
53*bb4ee6a4SAndroid Build Coastguard Worker impl EventToken for u32 {
as_raw_token(&self) -> u6454*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_token(&self) -> u64 {
55*bb4ee6a4SAndroid Build Coastguard Worker         u64::from(*self)
56*bb4ee6a4SAndroid Build Coastguard Worker     }
57*bb4ee6a4SAndroid Build Coastguard Worker 
from_raw_token(data: u64) -> Self58*bb4ee6a4SAndroid Build Coastguard Worker     fn from_raw_token(data: u64) -> Self {
59*bb4ee6a4SAndroid Build Coastguard Worker         data as Self
60*bb4ee6a4SAndroid Build Coastguard Worker     }
61*bb4ee6a4SAndroid Build Coastguard Worker }
62*bb4ee6a4SAndroid Build Coastguard Worker 
63*bb4ee6a4SAndroid Build Coastguard Worker impl EventToken for u16 {
as_raw_token(&self) -> u6464*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_token(&self) -> u64 {
65*bb4ee6a4SAndroid Build Coastguard Worker         u64::from(*self)
66*bb4ee6a4SAndroid Build Coastguard Worker     }
67*bb4ee6a4SAndroid Build Coastguard Worker 
from_raw_token(data: u64) -> Self68*bb4ee6a4SAndroid Build Coastguard Worker     fn from_raw_token(data: u64) -> Self {
69*bb4ee6a4SAndroid Build Coastguard Worker         data as Self
70*bb4ee6a4SAndroid Build Coastguard Worker     }
71*bb4ee6a4SAndroid Build Coastguard Worker }
72*bb4ee6a4SAndroid Build Coastguard Worker 
73*bb4ee6a4SAndroid Build Coastguard Worker impl EventToken for u8 {
as_raw_token(&self) -> u6474*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_token(&self) -> u64 {
75*bb4ee6a4SAndroid Build Coastguard Worker         u64::from(*self)
76*bb4ee6a4SAndroid Build Coastguard Worker     }
77*bb4ee6a4SAndroid Build Coastguard Worker 
from_raw_token(data: u64) -> Self78*bb4ee6a4SAndroid Build Coastguard Worker     fn from_raw_token(data: u64) -> Self {
79*bb4ee6a4SAndroid Build Coastguard Worker         data as Self
80*bb4ee6a4SAndroid Build Coastguard Worker     }
81*bb4ee6a4SAndroid Build Coastguard Worker }
82*bb4ee6a4SAndroid Build Coastguard Worker 
83*bb4ee6a4SAndroid Build Coastguard Worker impl EventToken for () {
as_raw_token(&self) -> u6484*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_token(&self) -> u64 {
85*bb4ee6a4SAndroid Build Coastguard Worker         0
86*bb4ee6a4SAndroid Build Coastguard Worker     }
87*bb4ee6a4SAndroid Build Coastguard Worker 
from_raw_token(_data: u64) -> Self88*bb4ee6a4SAndroid Build Coastguard Worker     fn from_raw_token(_data: u64) -> Self {}
89*bb4ee6a4SAndroid Build Coastguard Worker }
90*bb4ee6a4SAndroid Build Coastguard Worker 
91*bb4ee6a4SAndroid Build Coastguard Worker /// Represents an event that has been signaled and waited for via a wait function.
92*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug)]
93*bb4ee6a4SAndroid Build Coastguard Worker pub struct TriggeredEvent<T: EventToken> {
94*bb4ee6a4SAndroid Build Coastguard Worker     pub token: T,
95*bb4ee6a4SAndroid Build Coastguard Worker     pub is_readable: bool,
96*bb4ee6a4SAndroid Build Coastguard Worker     pub is_writable: bool,
97*bb4ee6a4SAndroid Build Coastguard Worker     pub is_hungup: bool,
98*bb4ee6a4SAndroid Build Coastguard Worker }
99*bb4ee6a4SAndroid Build Coastguard Worker 
100*bb4ee6a4SAndroid Build Coastguard Worker /// Represents types of events to watch for.
101*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, PartialEq, Eq)]
102*bb4ee6a4SAndroid Build Coastguard Worker pub enum EventType {
103*bb4ee6a4SAndroid Build Coastguard Worker     // Used to to temporarily stop waiting for events without
104*bb4ee6a4SAndroid Build Coastguard Worker     // removing the associated descriptor from the WaitContext.
105*bb4ee6a4SAndroid Build Coastguard Worker     // In most cases if a descriptor no longer needs to be
106*bb4ee6a4SAndroid Build Coastguard Worker     // waited on, prefer removing it entirely with
107*bb4ee6a4SAndroid Build Coastguard Worker     // WaitContext#delete
108*bb4ee6a4SAndroid Build Coastguard Worker     None,
109*bb4ee6a4SAndroid Build Coastguard Worker     Read,
110*bb4ee6a4SAndroid Build Coastguard Worker     Write,
111*bb4ee6a4SAndroid Build Coastguard Worker     ReadWrite,
112*bb4ee6a4SAndroid Build Coastguard Worker }
113*bb4ee6a4SAndroid Build Coastguard Worker 
114*bb4ee6a4SAndroid Build Coastguard Worker /// Used to wait for multiple objects which are eligible for waiting.
115*bb4ee6a4SAndroid Build Coastguard Worker ///
116*bb4ee6a4SAndroid Build Coastguard Worker /// # Example
117*bb4ee6a4SAndroid Build Coastguard Worker ///
118*bb4ee6a4SAndroid Build Coastguard Worker /// ```
119*bb4ee6a4SAndroid Build Coastguard Worker /// use base::{Event, EventToken, Result, WaitContext};
120*bb4ee6a4SAndroid Build Coastguard Worker ///
121*bb4ee6a4SAndroid Build Coastguard Worker /// #[derive(EventToken, Copy, Clone, Debug, PartialEq, Eq)]
122*bb4ee6a4SAndroid Build Coastguard Worker /// enum ExampleToken {
123*bb4ee6a4SAndroid Build Coastguard Worker ///    SomeEvent(u32),
124*bb4ee6a4SAndroid Build Coastguard Worker ///    AnotherEvent,
125*bb4ee6a4SAndroid Build Coastguard Worker /// }
126*bb4ee6a4SAndroid Build Coastguard Worker ///
127*bb4ee6a4SAndroid Build Coastguard Worker /// let evt1 = Event::new()?;
128*bb4ee6a4SAndroid Build Coastguard Worker /// let evt2 = Event::new()?;
129*bb4ee6a4SAndroid Build Coastguard Worker /// let another_evt = Event::new()?;
130*bb4ee6a4SAndroid Build Coastguard Worker ///
131*bb4ee6a4SAndroid Build Coastguard Worker /// let ctx: WaitContext<ExampleToken> = WaitContext::build_with(&[
132*bb4ee6a4SAndroid Build Coastguard Worker ///     (&evt1, ExampleToken::SomeEvent(1)),
133*bb4ee6a4SAndroid Build Coastguard Worker ///     (&evt2, ExampleToken::SomeEvent(2)),
134*bb4ee6a4SAndroid Build Coastguard Worker ///     (&another_evt, ExampleToken::AnotherEvent),
135*bb4ee6a4SAndroid Build Coastguard Worker /// ])?;
136*bb4ee6a4SAndroid Build Coastguard Worker ///
137*bb4ee6a4SAndroid Build Coastguard Worker /// // Trigger one of the `SomeEvent` events.
138*bb4ee6a4SAndroid Build Coastguard Worker /// evt2.signal()?;
139*bb4ee6a4SAndroid Build Coastguard Worker ///
140*bb4ee6a4SAndroid Build Coastguard Worker /// // Wait for an event to fire. `wait()` will return immediately in this example because `evt2`
141*bb4ee6a4SAndroid Build Coastguard Worker /// // has already been triggered, but in normal use, `wait()` will block until at least one event
142*bb4ee6a4SAndroid Build Coastguard Worker /// // is signaled by another thread or process.
143*bb4ee6a4SAndroid Build Coastguard Worker /// let events = ctx.wait()?;
144*bb4ee6a4SAndroid Build Coastguard Worker /// let tokens: Vec<ExampleToken> = events.iter().filter(|e| e.is_readable)
145*bb4ee6a4SAndroid Build Coastguard Worker ///     .map(|e| e.token).collect();
146*bb4ee6a4SAndroid Build Coastguard Worker /// assert_eq!(tokens, [ExampleToken::SomeEvent(2)]);
147*bb4ee6a4SAndroid Build Coastguard Worker ///
148*bb4ee6a4SAndroid Build Coastguard Worker /// // Reset evt2 so it doesn't trigger again in the next `wait()` call.
149*bb4ee6a4SAndroid Build Coastguard Worker /// let _ = evt2.reset()?;
150*bb4ee6a4SAndroid Build Coastguard Worker ///
151*bb4ee6a4SAndroid Build Coastguard Worker /// // Trigger a different event.
152*bb4ee6a4SAndroid Build Coastguard Worker /// another_evt.signal()?;
153*bb4ee6a4SAndroid Build Coastguard Worker ///
154*bb4ee6a4SAndroid Build Coastguard Worker /// let events = ctx.wait()?;
155*bb4ee6a4SAndroid Build Coastguard Worker /// let tokens: Vec<ExampleToken> = events.iter().filter(|e| e.is_readable)
156*bb4ee6a4SAndroid Build Coastguard Worker ///     .map(|e| e.token).collect();
157*bb4ee6a4SAndroid Build Coastguard Worker /// assert_eq!(tokens, [ExampleToken::AnotherEvent]);
158*bb4ee6a4SAndroid Build Coastguard Worker ///
159*bb4ee6a4SAndroid Build Coastguard Worker /// let _ = another_evt.reset()?;
160*bb4ee6a4SAndroid Build Coastguard Worker /// # Ok::<(), base::Error>(())
161*bb4ee6a4SAndroid Build Coastguard Worker /// ```
162*bb4ee6a4SAndroid Build Coastguard Worker pub struct WaitContext<T: EventToken>(pub(crate) EventContext<T>);
163*bb4ee6a4SAndroid Build Coastguard Worker 
164*bb4ee6a4SAndroid Build Coastguard Worker impl<T: EventToken> WaitContext<T> {
165*bb4ee6a4SAndroid Build Coastguard Worker     /// Creates a new WaitContext.
new() -> Result<WaitContext<T>>166*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new() -> Result<WaitContext<T>> {
167*bb4ee6a4SAndroid Build Coastguard Worker         EventContext::new().map(WaitContext)
168*bb4ee6a4SAndroid Build Coastguard Worker     }
169*bb4ee6a4SAndroid Build Coastguard Worker 
170*bb4ee6a4SAndroid Build Coastguard Worker     /// Creates a new WaitContext with the the associated triggers.
build_with(triggers: &[(&dyn AsRawDescriptor, T)]) -> Result<WaitContext<T>>171*bb4ee6a4SAndroid Build Coastguard Worker     pub fn build_with(triggers: &[(&dyn AsRawDescriptor, T)]) -> Result<WaitContext<T>> {
172*bb4ee6a4SAndroid Build Coastguard Worker         let ctx = WaitContext::new()?;
173*bb4ee6a4SAndroid Build Coastguard Worker         ctx.add_many(triggers)?;
174*bb4ee6a4SAndroid Build Coastguard Worker         Ok(ctx)
175*bb4ee6a4SAndroid Build Coastguard Worker     }
176*bb4ee6a4SAndroid Build Coastguard Worker 
177*bb4ee6a4SAndroid Build Coastguard Worker     /// Adds a trigger to the WaitContext.
add(&self, descriptor: &dyn AsRawDescriptor, token: T) -> Result<()>178*bb4ee6a4SAndroid Build Coastguard Worker     pub fn add(&self, descriptor: &dyn AsRawDescriptor, token: T) -> Result<()> {
179*bb4ee6a4SAndroid Build Coastguard Worker         self.add_for_event(descriptor, EventType::Read, token)
180*bb4ee6a4SAndroid Build Coastguard Worker     }
181*bb4ee6a4SAndroid Build Coastguard Worker 
182*bb4ee6a4SAndroid Build Coastguard Worker     /// Adds a trigger to the WaitContext watching for a specific type of event
add_for_event( &self, descriptor: &dyn AsRawDescriptor, event_type: EventType, token: T, ) -> Result<()>183*bb4ee6a4SAndroid Build Coastguard Worker     pub fn add_for_event(
184*bb4ee6a4SAndroid Build Coastguard Worker         &self,
185*bb4ee6a4SAndroid Build Coastguard Worker         descriptor: &dyn AsRawDescriptor,
186*bb4ee6a4SAndroid Build Coastguard Worker         event_type: EventType,
187*bb4ee6a4SAndroid Build Coastguard Worker         token: T,
188*bb4ee6a4SAndroid Build Coastguard Worker     ) -> Result<()> {
189*bb4ee6a4SAndroid Build Coastguard Worker         self.0.add_for_event(descriptor, event_type, token)
190*bb4ee6a4SAndroid Build Coastguard Worker     }
191*bb4ee6a4SAndroid Build Coastguard Worker 
192*bb4ee6a4SAndroid Build Coastguard Worker     /// Adds multiple triggers to the WaitContext.
add_many(&self, triggers: &[(&dyn AsRawDescriptor, T)]) -> Result<()>193*bb4ee6a4SAndroid Build Coastguard Worker     pub fn add_many(&self, triggers: &[(&dyn AsRawDescriptor, T)]) -> Result<()> {
194*bb4ee6a4SAndroid Build Coastguard Worker         for trigger in triggers {
195*bb4ee6a4SAndroid Build Coastguard Worker             self.add(trigger.0, T::from_raw_token(trigger.1.as_raw_token()))?
196*bb4ee6a4SAndroid Build Coastguard Worker         }
197*bb4ee6a4SAndroid Build Coastguard Worker         Ok(())
198*bb4ee6a4SAndroid Build Coastguard Worker     }
199*bb4ee6a4SAndroid Build Coastguard Worker 
200*bb4ee6a4SAndroid Build Coastguard Worker     /// Modifies a trigger already added to the WaitContext. If the descriptor is
201*bb4ee6a4SAndroid Build Coastguard Worker     /// already registered, its associated token will be updated.
modify( &self, descriptor: &dyn AsRawDescriptor, event_type: EventType, token: T, ) -> Result<()>202*bb4ee6a4SAndroid Build Coastguard Worker     pub fn modify(
203*bb4ee6a4SAndroid Build Coastguard Worker         &self,
204*bb4ee6a4SAndroid Build Coastguard Worker         descriptor: &dyn AsRawDescriptor,
205*bb4ee6a4SAndroid Build Coastguard Worker         event_type: EventType,
206*bb4ee6a4SAndroid Build Coastguard Worker         token: T,
207*bb4ee6a4SAndroid Build Coastguard Worker     ) -> Result<()> {
208*bb4ee6a4SAndroid Build Coastguard Worker         self.0.modify(descriptor, event_type, token)
209*bb4ee6a4SAndroid Build Coastguard Worker     }
210*bb4ee6a4SAndroid Build Coastguard Worker 
211*bb4ee6a4SAndroid Build Coastguard Worker     /// Removes the given handle from triggers registered in the WaitContext if
212*bb4ee6a4SAndroid Build Coastguard Worker     /// present.
delete(&self, descriptor: &dyn AsRawDescriptor) -> Result<()>213*bb4ee6a4SAndroid Build Coastguard Worker     pub fn delete(&self, descriptor: &dyn AsRawDescriptor) -> Result<()> {
214*bb4ee6a4SAndroid Build Coastguard Worker         self.0.delete(descriptor)
215*bb4ee6a4SAndroid Build Coastguard Worker     }
216*bb4ee6a4SAndroid Build Coastguard Worker 
217*bb4ee6a4SAndroid Build Coastguard Worker     /// Waits for one or more of the registered triggers to become signaled.
wait(&self) -> Result<SmallVec<[TriggeredEvent<T>; 16]>>218*bb4ee6a4SAndroid Build Coastguard Worker     pub fn wait(&self) -> Result<SmallVec<[TriggeredEvent<T>; 16]>> {
219*bb4ee6a4SAndroid Build Coastguard Worker         self.wait_timeout(Duration::new(i64::MAX as u64, 0))
220*bb4ee6a4SAndroid Build Coastguard Worker     }
221*bb4ee6a4SAndroid Build Coastguard Worker 
222*bb4ee6a4SAndroid Build Coastguard Worker     /// Waits for one or more of the registered triggers to become signaled, failing if no triggers
223*bb4ee6a4SAndroid Build Coastguard Worker     /// are signaled before the designated timeout has elapsed.
wait_timeout(&self, timeout: Duration) -> Result<SmallVec<[TriggeredEvent<T>; 16]>>224*bb4ee6a4SAndroid Build Coastguard Worker     pub fn wait_timeout(&self, timeout: Duration) -> Result<SmallVec<[TriggeredEvent<T>; 16]>> {
225*bb4ee6a4SAndroid Build Coastguard Worker         self.0.wait_timeout(timeout)
226*bb4ee6a4SAndroid Build Coastguard Worker     }
227*bb4ee6a4SAndroid Build Coastguard Worker }
228*bb4ee6a4SAndroid Build Coastguard Worker 
229*bb4ee6a4SAndroid Build Coastguard Worker impl<T: EventToken> AsRawDescriptor for WaitContext<T> {
as_raw_descriptor(&self) -> RawDescriptor230*bb4ee6a4SAndroid Build Coastguard Worker     fn as_raw_descriptor(&self) -> RawDescriptor {
231*bb4ee6a4SAndroid Build Coastguard Worker         self.0.as_raw_descriptor()
232*bb4ee6a4SAndroid Build Coastguard Worker     }
233*bb4ee6a4SAndroid Build Coastguard Worker }
234*bb4ee6a4SAndroid Build Coastguard Worker 
235*bb4ee6a4SAndroid Build Coastguard Worker #[cfg(test)]
236*bb4ee6a4SAndroid Build Coastguard Worker mod tests {
237*bb4ee6a4SAndroid Build Coastguard Worker     use base_event_token_derive::EventToken;
238*bb4ee6a4SAndroid Build Coastguard Worker 
239*bb4ee6a4SAndroid Build Coastguard Worker     use super::*;
240*bb4ee6a4SAndroid Build Coastguard Worker 
241*bb4ee6a4SAndroid Build Coastguard Worker     #[test]
242*bb4ee6a4SAndroid Build Coastguard Worker     #[allow(dead_code)]
event_token_derive()243*bb4ee6a4SAndroid Build Coastguard Worker     fn event_token_derive() {
244*bb4ee6a4SAndroid Build Coastguard Worker         #[derive(EventToken)]
245*bb4ee6a4SAndroid Build Coastguard Worker         enum EmptyToken {}
246*bb4ee6a4SAndroid Build Coastguard Worker 
247*bb4ee6a4SAndroid Build Coastguard Worker         #[derive(PartialEq, Debug, EventToken)]
248*bb4ee6a4SAndroid Build Coastguard Worker         enum Token {
249*bb4ee6a4SAndroid Build Coastguard Worker             Alpha,
250*bb4ee6a4SAndroid Build Coastguard Worker             Beta,
251*bb4ee6a4SAndroid Build Coastguard Worker             // comments
252*bb4ee6a4SAndroid Build Coastguard Worker             Gamma(u32),
253*bb4ee6a4SAndroid Build Coastguard Worker             Delta { index: usize },
254*bb4ee6a4SAndroid Build Coastguard Worker             Omega,
255*bb4ee6a4SAndroid Build Coastguard Worker         }
256*bb4ee6a4SAndroid Build Coastguard Worker 
257*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
258*bb4ee6a4SAndroid Build Coastguard Worker             Token::from_raw_token(Token::Alpha.as_raw_token()),
259*bb4ee6a4SAndroid Build Coastguard Worker             Token::Alpha
260*bb4ee6a4SAndroid Build Coastguard Worker         );
261*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
262*bb4ee6a4SAndroid Build Coastguard Worker             Token::from_raw_token(Token::Beta.as_raw_token()),
263*bb4ee6a4SAndroid Build Coastguard Worker             Token::Beta
264*bb4ee6a4SAndroid Build Coastguard Worker         );
265*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
266*bb4ee6a4SAndroid Build Coastguard Worker             Token::from_raw_token(Token::Gamma(55).as_raw_token()),
267*bb4ee6a4SAndroid Build Coastguard Worker             Token::Gamma(55)
268*bb4ee6a4SAndroid Build Coastguard Worker         );
269*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
270*bb4ee6a4SAndroid Build Coastguard Worker             Token::from_raw_token(Token::Delta { index: 100 }.as_raw_token()),
271*bb4ee6a4SAndroid Build Coastguard Worker             Token::Delta { index: 100 }
272*bb4ee6a4SAndroid Build Coastguard Worker         );
273*bb4ee6a4SAndroid Build Coastguard Worker         assert_eq!(
274*bb4ee6a4SAndroid Build Coastguard Worker             Token::from_raw_token(Token::Omega.as_raw_token()),
275*bb4ee6a4SAndroid Build Coastguard Worker             Token::Omega
276*bb4ee6a4SAndroid Build Coastguard Worker         );
277*bb4ee6a4SAndroid Build Coastguard Worker     }
278*bb4ee6a4SAndroid Build Coastguard Worker }
279