1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 //! Common utilities used by other modules within this crate. 15 16 use handle_map::HandleLike; 17 18 /// Type-level predicate for handle types which uniformly hold a lock 19 /// for longer than some other handle type in API calls. 20 /// 21 /// Largely an informative marker trait used to indicate the 22 /// lock ordering on types. 23 #[allow(dead_code)] 24 pub(crate) trait LocksLongerThan<H: HandleLike>: HandleLike {} 25 26 /// Trait which canonicalizes the relationship between FFI 27 /// tagged-unions and their tags 28 pub trait FfiEnum { 29 /// The [FFI-safe] type of tags used to identify 30 /// variants of this tagged union. 31 type Kind; 32 33 /// Returns the tag for this FFI-safe tagged union. kind(&self) -> Self::Kind34 fn kind(&self) -> Self::Kind; 35 } 36 37 /// Declares a method of the given name which attempts to cast 38 /// the enclosing enum to the payload held under the given 39 /// variant name, yielding a result of the given type wrapped 40 /// in an `Option::Some`. 41 /// 42 /// If the enclosing enum turns out to not be the requested 43 /// variant, the generated method will return `None`. 44 #[macro_export] 45 macro_rules! declare_enum_cast { 46 ($projection_method_name:ident, $variant_enum_name:ident, $variant_type_name:ty) => { 47 #[doc = concat!("Attempts to cast `self` to the `", stringify!($variant_enum_name), 48 "` variant, returning `None` in the \ncase where the passed value is of a different enum variant.")] 49 pub fn $projection_method_name(self) -> Option<$variant_type_name> { 50 match self { 51 Self::$variant_enum_name(x) => Some(x), 52 _ => None, 53 } 54 } 55 } 56 } 57