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 //! Several macros 17 18 #![allow(dead_code)] 19 20 /// macro define_enum can be used to define enum type, which is associated with several helper functions. 21 #[macro_export] 22 macro_rules! define_enum { 23 { 24 $name:ident { 25 $( $item:ident ), * 26 } 27 } => { 28 /// enum $name 29 #[allow(dead_code)] 30 #[derive(Hash, PartialEq, Eq, Clone)] 31 #[repr(u32)] 32 pub enum $name { 33 $( 34 /// variant $item 35 $item, 36 )* 37 } 38 39 impl TryFrom<u32> for $name { 40 type Error = i32; 41 fn try_from(code: u32) -> std::result::Result<Self, Self::Error> { 42 match code { 43 $( 44 _ if code == Self::$item as u32 => { 45 Ok(Self::$item) 46 } 47 )* 48 _ => { 49 Err(-1) 50 } 51 } 52 } 53 } 54 55 impl ipc_rust::Serialize for $name { 56 fn serialize(&self, parcel: &mut ipc_rust::BorrowedMsgParcel<'_>) -> ipc_rust::IpcResult<()> { 57 match self { 58 $( 59 Self::$item => { 60 (Self::$item as u32).serialize(parcel) 61 } 62 )* 63 } 64 } 65 } 66 67 impl ipc_rust::Deserialize for $name { 68 fn deserialize(parcel: &ipc_rust::BorrowedMsgParcel<'_>) -> ipc_rust::IpcResult<Self> { 69 match u32::deserialize(parcel) { 70 Ok(val) => { 71 match $name::try_from(val) { 72 Ok(e) => { 73 Ok(e) 74 } 75 Err(_) => { 76 Err(ipc_rust::IpcStatusCode::InvalidValue) 77 } 78 } 79 } 80 Err(err) => { 81 Err(err) 82 } 83 } 84 } 85 } 86 }; 87 } 88 89 /// struct InnerFunctionTracer 90 pub struct InnerFunctionTracer<'a> { 91 log: Box<dyn Fn(&str, &str)>, 92 func_name: &'a str 93 } 94 95 impl<'a> InnerFunctionTracer<'a> { 96 /// TODO: add documentation. new(log: Box<dyn Fn(&str, &str)>, func_name: &'a str) -> Self97 pub fn new(log: Box<dyn Fn(&str, &str)>, func_name: &'a str) -> Self { 98 log(func_name, "enter"); 99 Self { 100 log, func_name 101 } 102 } 103 } 104 105 impl<'a> Drop for InnerFunctionTracer<'a> { drop(&mut self)106 fn drop(&mut self) { 107 (self.log)(self.func_name, "leave"); 108 } 109 } 110 111 /// call_debug_enter 112 #[macro_export] 113 macro_rules! call_debug_enter { 114 ( 115 $func_name: literal 116 ) => { 117 let __inner_function_tracer__ = $crate::InnerFunctionTracer::new( 118 Box::new(|func_name: &str, action: &str| { 119 hilog_rust::debug!(LOG_LABEL, "in {}: {}", @public(func_name), @public(action)); 120 }), 121 $func_name 122 ); 123 }; 124 } 125 126 /// call_info_trace 127 #[macro_export] 128 macro_rules! call_info_trace { 129 ( 130 $func_name: literal 131 ) => { 132 let __inner_function_tracer__ = $crate::InnerFunctionTracer::new( 133 Box::new(|func_name: &str, action: &str| { 134 hilog_rust::info!(LOG_LABEL, "in {}: {}", @public(func_name), @public(action)); 135 }), 136 $func_name 137 ); 138 }; 139 } 140