1 // Copyright 2022 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use thiserror::Error; 6 7 use crate::bindings; 8 9 /// A wrapper over `VAGenericValue` giving us safe access to the underlying union members. 10 #[derive(Debug)] 11 pub enum GenericValue { 12 /// A wrapper over VAGenericValueTypeInteger 13 Integer(i32), 14 /// A wrapper over VAGenericValueTypeFloat 15 Float(f32), 16 /// A wrapper over VAGenericValueTypePointer 17 Pointer(*mut std::os::raw::c_void), 18 /// A wrapper over VAGenericValueTypeFunc 19 Func(bindings::VAGenericFunc), 20 } 21 22 #[derive(Debug, Error)] 23 pub enum GenericValueError { 24 #[error("unexpected VAGenericValueType {0}")] 25 UnexpectedType(u32), 26 } 27 28 impl TryFrom<bindings::VAGenericValue> for GenericValue { 29 type Error = GenericValueError; 30 try_from(value: bindings::VAGenericValue) -> Result<Self, Self::Error>31 fn try_from(value: bindings::VAGenericValue) -> Result<Self, Self::Error> { 32 // Safe because we check the type before accessing the union. 33 match value.type_ { 34 // Safe because we check the type before accessing the union. 35 bindings::VAGenericValueType::VAGenericValueTypeInteger => { 36 Ok(Self::Integer(unsafe { value.value.i })) 37 } 38 bindings::VAGenericValueType::VAGenericValueTypeFloat => { 39 Ok(Self::Float(unsafe { value.value.f })) 40 } 41 bindings::VAGenericValueType::VAGenericValueTypePointer => { 42 Ok(Self::Pointer(unsafe { value.value.p })) 43 } 44 bindings::VAGenericValueType::VAGenericValueTypeFunc => { 45 Ok(Self::Func(unsafe { value.value.fn_ })) 46 } 47 _ => Err(GenericValueError::UnexpectedType(value.type_)), 48 } 49 } 50 } 51