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