xref: /aosp_15_r20/external/crosvm/devices/src/virtio/video/macros.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 //! Macros that helps virtio video implementation.
6*bb4ee6a4SAndroid Build Coastguard Worker 
7*bb4ee6a4SAndroid Build Coastguard Worker /// Implements TryFrom<data_model::Le32> for an enum that implements `enumn::N`.
8*bb4ee6a4SAndroid Build Coastguard Worker #[macro_export]
9*bb4ee6a4SAndroid Build Coastguard Worker macro_rules! impl_try_from_le32_for_enumn {
10*bb4ee6a4SAndroid Build Coastguard Worker     ($ty:ty, $name:literal) => {
11*bb4ee6a4SAndroid Build Coastguard Worker         impl TryFrom<Le32> for $ty {
12*bb4ee6a4SAndroid Build Coastguard Worker             type Error = ReadCmdError;
13*bb4ee6a4SAndroid Build Coastguard Worker 
14*bb4ee6a4SAndroid Build Coastguard Worker             fn try_from(x: Le32) -> Result<Self, Self::Error> {
15*bb4ee6a4SAndroid Build Coastguard Worker                 let v: u32 = x.into();
16*bb4ee6a4SAndroid Build Coastguard Worker                 Self::n(v).ok_or_else(|| {
17*bb4ee6a4SAndroid Build Coastguard Worker                     error!(concat!("invalid ", $name, ": {}"), v);
18*bb4ee6a4SAndroid Build Coastguard Worker                     ReadCmdError::InvalidArgument
19*bb4ee6a4SAndroid Build Coastguard Worker                 })
20*bb4ee6a4SAndroid Build Coastguard Worker             }
21*bb4ee6a4SAndroid Build Coastguard Worker         }
22*bb4ee6a4SAndroid Build Coastguard Worker     };
23*bb4ee6a4SAndroid Build Coastguard Worker }
24*bb4ee6a4SAndroid Build Coastguard Worker 
25*bb4ee6a4SAndroid Build Coastguard Worker /// Implements `From` between two structs whose each field implements `From` each other.
26*bb4ee6a4SAndroid Build Coastguard Worker #[macro_export]
27*bb4ee6a4SAndroid Build Coastguard Worker macro_rules! impl_from_for_interconvertible_structs {
28*bb4ee6a4SAndroid Build Coastguard Worker     ($t1:ident, $t2:ident, $($v:ident),+) => {
29*bb4ee6a4SAndroid Build Coastguard Worker         impl_from_for_interconvertible_structs_core!($t1, $t2, $( $v ),+ );
30*bb4ee6a4SAndroid Build Coastguard Worker         impl_from_for_interconvertible_structs_core!($t2, $t1, $( $v ),+ );
31*bb4ee6a4SAndroid Build Coastguard Worker     };
32*bb4ee6a4SAndroid Build Coastguard Worker }
33*bb4ee6a4SAndroid Build Coastguard Worker 
34*bb4ee6a4SAndroid Build Coastguard Worker macro_rules! impl_from_for_interconvertible_structs_core {
35*bb4ee6a4SAndroid Build Coastguard Worker     ($t1:ident, $t2:ident, $($v:ident),+) => {
36*bb4ee6a4SAndroid Build Coastguard Worker         impl From<$t1> for $t2 {
37*bb4ee6a4SAndroid Build Coastguard Worker             #[allow(clippy::needless_update)]
38*bb4ee6a4SAndroid Build Coastguard Worker             fn from(x :$t1) -> Self {
39*bb4ee6a4SAndroid Build Coastguard Worker                 $t2 {
40*bb4ee6a4SAndroid Build Coastguard Worker                     $( $v: x.$v.into(), )+
41*bb4ee6a4SAndroid Build Coastguard Worker                     ..Default::default() // for paddings
42*bb4ee6a4SAndroid Build Coastguard Worker                 }
43*bb4ee6a4SAndroid Build Coastguard Worker             }
44*bb4ee6a4SAndroid Build Coastguard Worker         }
45*bb4ee6a4SAndroid Build Coastguard Worker     };
46*bb4ee6a4SAndroid Build Coastguard Worker }
47