1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 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 */ 15 16 //! This module defines the tool macro of the enumeration type. 17 18 /// Macro to implement TryFrom and Display for enumeration types. 19 /// 20 /// # Examples 21 /// 22 /// ``` 23 /// impl_tag_trait! { 24 /// enum Color { 25 /// GREEN = 0, 26 /// YELLOW = 1, 27 /// } 28 /// } 29 /// ``` 30 #[macro_export] 31 macro_rules! impl_tag_trait { 32 ($(#[$meta:meta])* $vis:vis enum $name:ident { 33 $($(#[$vmeta:meta])* $vname:ident $(= $val:expr)?,)* 34 }) => { 35 $(#[$meta])* 36 $vis enum $name { 37 $($(#[$vmeta])* $vname $(= $val)?,)* 38 } 39 40 impl std::convert::TryFrom<u32> for $name { 41 type Error = $crate::AssetError; 42 43 fn try_from(v: u32) -> std::result::Result<Self, Self::Error> { 44 match v { 45 $(x if x == $name::$vname as u32 => Ok($name::$vname),)* 46 _ => { 47 $crate::log_throw_error!($crate::ErrCode::InvalidArgument, 48 "[FATAL]Type[{}] try from u32[{}] failed.", stringify!($name), v) 49 } 50 } 51 } 52 } 53 54 impl std::fmt::Display for $name { 55 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 56 match self { 57 $($name::$vname => { 58 write!(f, "{}", stringify!($name::$vname)) 59 },)* 60 } 61 } 62 } 63 } 64 } 65 66 /// Macro to implement TryFrom and Display for enumeration types. 67 /// 68 /// # Examples 69 /// 70 /// ``` 71 /// impl_enum_trait! { 72 /// enum Color { 73 /// GREEN = 0, 74 /// YELLOW = 1, 75 /// } 76 /// } 77 /// ``` 78 #[macro_export] 79 macro_rules! impl_enum_trait { 80 ($(#[$meta:meta])* $vis:vis enum $name:ident { 81 $($(#[$vmeta:meta])* $vname:ident $(= $val:expr)?,)* 82 }) => { 83 $(#[$meta])* 84 $vis enum $name { 85 $($(#[$vmeta])* $vname $(= $val)?,)* 86 } 87 88 impl std::convert::TryFrom<u32> for $name { 89 type Error = $crate::AssetError; 90 91 fn try_from(v: u32) -> std::result::Result<Self, Self::Error> { 92 match v { 93 $(x if x == $name::$vname as u32 => Ok($name::$vname),)* 94 _ => { 95 $crate::log_throw_error!($crate::ErrCode::InvalidArgument, 96 "[FATAL]Type[{}] try from u32[{}] failed.", stringify!($name), v) 97 } 98 } 99 } 100 } 101 102 impl std::fmt::Display for $name { 103 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 104 match self { 105 $($name::$vname => { 106 write!(f, "{}", stringify!($name::$vname)) 107 },)* 108 } 109 } 110 } 111 112 impl $crate::Conversion for $name { 113 fn data_type(&self) -> $crate::DataType { 114 $crate::DataType::Number 115 } 116 117 fn into_value(self) -> $crate::Value { 118 $crate::Value::Number(self as u32) 119 } 120 } 121 } 122 } 123 124 /// Print log and throw AssetError. 125 /// 126 /// # Examples 127 /// 128 /// ``` 129 /// log_throw_error!(ErrCode::InvalidArgument, "hello, {}", "world"); 130 /// ``` 131 #[macro_export] 132 macro_rules! log_throw_error { 133 ($code:expr, $($arg:tt)*) => {{ 134 let str = format!($($arg)*); 135 asset_log::loge!("{}", str); 136 Err($crate::AssetError { 137 code: $code, 138 msg: str 139 }) 140 }}; 141 } 142 143 /// Throw AssetError. 144 /// 145 /// # Examples 146 /// 147 /// ``` 148 /// throw_error!(ErrCode::InvalidArgument, "hello, {}", "world"); 149 /// ``` 150 #[macro_export] 151 macro_rules! throw_error { 152 ($code:expr, $($arg:tt)*) => {{ 153 let str = format!($($arg)*); 154 Err($crate::AssetError { 155 code: $code, 156 msg: str 157 }) 158 }}; 159 } 160 161 /// Impl from trait for u32. 162 /// 163 /// # Examples 164 /// 165 /// ``` 166 /// impl_from_for_u32!(Accessibility); 167 /// ``` 168 #[macro_export] 169 macro_rules! impl_from_for_u32 { 170 ($t:ty) => { 171 impl From<$t> for u32 { 172 #[inline(always)] 173 fn from(value: $t) -> Self { 174 value as u32 175 } 176 } 177 }; 178 } 179