use std::mem;
// Placeholder for the custom `utf8` type (assuming it’s a string-like type)
#[derive(Clone)]
struct Utf8 {
data: String,
length: usize,
}
// Placeholder for the `guid` type (assuming it’s a 16-byte structure)
#[derive(Clone, Copy)]
struct Guid {
data: [u8; 16],
}
// Enum to represent the variant types (similar to `variant_type` in C++)
#[derive(Clone, Copy, PartialEq)]
enum VariantType {
Unknown,
Bool,
Int8,
Int16,
Int32,
Int64,
UInt8,
UInt16,
UInt32,
UInt64,
CFloat,
CDouble,
Pointer,
String,
Utf8String,
WString,
Binary,
Guid,
}
// Struct to hold the variant data
#[derive(Clone)]
pub struct Variant {
vtype: VariantType,
size: usize,
value: VariantValue,
}
// Enum to store the actual data
#[derive(Clone)]
enum VariantValue {
Unknown,
Bool(bool),
Int8(i8),
Int16(i16),
Int32(i32),
Int64(i64),
UInt8(u8),
UInt16(u16),
UInt32(u32),
UInt64(u64),
CFloat(f32),
CDouble(f64),
Pointer(*mut u8), // Unsafe pointer for raw pointer compatibility
String(String), // Owned string
Utf8String(String), // Owned UTF-8 string
WString(Vec<u16>), // Owned wide string
Binary(Vec<u8>), // Owned binary data
Guid(Guid),
StringRef(&'static str), // Non-owning string reference
}
impl Variant {
// Default constructor
pub fn new() -> Self {
Variant {
vtype: VariantType::Unknown,
size: 0,
value: VariantValue::Unknown,
}
}
// Constructor for bool
pub fn from_bool(b: bool) -> Self {
Variant {
vtype: VariantType::Bool,
size: mem::size_of::<bool>(),
value: VariantValue::Bool(b),
}
}
// Constructor for i8
pub fn from_i8(v: i8) -> Self {
Variant {
vtype: VariantType::Int8,
size: mem::size_of::<i8>(),
value: VariantValue::Int8(v),
}
}
// Constructor for i16
pub fn from_i16(v: i16) -> Self {
Variant {
vtype: VariantType::Int16,
size: mem::size_of::<i16>(),
value: VariantValue::Int16(v),
}
}
// Constructor for i32
pub fn from_i32(v: i32) -> Self {
Variant {
vtype: VariantType::Int32,
size: mem::size_of::<i32>(),
value: VariantValue::Int32(v),
}
}
// Constructor for i64
pub fn from_i64(v: i64) -> Self {
Variant {
vtype: VariantType::Int64,
size: mem::size_of::<i64>(),
value: VariantValue::Int64(v),
}
}
// Constructor for u8
pub fn from_u8(v: u8) -> Self {
Variant {
vtype: VariantType::UInt8,
size: mem::size_of::<u8>(),
value: VariantValue::UInt8(v),
}
}
// Constructor for u16
pub fn from_u16(v: u16) -> Self {
Variant {
vtype: VariantType::UInt16,
size: mem::size_of::<u16>(),
value: VariantValue::UInt16(v),
}
}
// Constructor for u32
pub fn from_u32(v: u32) -> Self {
Variant {
vtype: VariantType::UInt32,
size: mem::size_of::<u32>(),
value: VariantValue::UInt32(v),
}
}
// Constructor for u64
pub fn from_u64(v: u64) -> Self {
Variant {
vtype: VariantType::UInt64,
size: mem::size_of::<u64>(),
value: VariantValue::UInt64(v),
}
}
// Constructor for f32
pub fn from_f32(v: f32) -> Self {
Variant {
vtype: VariantType::CFloat,
size: mem::size_of::<f32>(),
value: VariantValue::CFloat(v),
}
}
// Constructor for f64
pub fn from_f64(v: f64) -> Self {
Variant {
vtype: VariantType::CDouble,
size: mem::size_of::<f64>(),
value: VariantValue::CDouble(v),
}
}
// Constructor for raw pointer
pub fn from_ptr(p: *mut u8) -> Self {
Variant {
vtype: VariantType::Pointer,
size: mem::size_of::<*mut u8>(),
value: VariantValue::Pointer(p),
}
}
// Constructor for owned string (from &str)
pub fn from_str(v: &str) -> Self {
Variant {
vtype: VariantType::String,
size: v.len(),
value: VariantValue::String(v.to_string()),
}
}
// Constructor for non-owning string (static lifetime)
pub fn from_str_ref(v: &'static str) -> Self {
Variant {
vtype: VariantType::String,
size: v.len(),
value: VariantValue::StringRef(v),
}
}
// Constructor for owned UTF-8 string
pub fn from_utf8_string(v: &str) -> Self {
Variant {
vtype: VariantType::Utf8String,
size: v.len(),
value: VariantValue::Utf8String(v.to_string()),
}
}
// Constructor for owned wide string (Vec<u16>)
pub fn from_wstr(v: &[u16]) -> Self {
Variant {
vtype: VariantType::WString,
size: v.len(),
value: VariantValue::WString(v.to_vec()),
}
}
// Constructor for owned binary data
pub fn from_binary(v: &[u8]) -> Self {
Variant {
vtype: VariantType::Binary,
size: v.len(),
value: VariantValue::Binary(v.to_vec()),
}
}
// Constructor for guid
pub fn from_guid(v: Guid) -> Self {
Variant {
vtype: VariantType::Guid,
size: mem::size_of::<Guid>(),
value: VariantValue::Guid(v),
}
}
// Constructor for custom Utf8 type
pub fn from_utf8(v: &Utf8) -> Self {
Variant {
vtype: VariantType::Utf8String,
size: v.length,
value: VariantValue::Utf8String(v.data.clone()),
}
}
// Constructor for custom type with raw data
pub fn from_raw(vtype: VariantType, data: &[u8], length: usize) -> Self {
Variant {
vtype,
size: length,
value: VariantValue::Binary(data.to_vec()),
}
}
}
// Optional: Implement Drop to handle cleanup for types requiring it (e.g., pointers)
impl Drop for Variant {
fn drop(&mut self) {
match self.value {
// No manual cleanup needed for String, Vec, etc., as they are managed by Rust
VariantValue::Pointer(_p) => {
// If the pointer needs manual cleanup, implement it here (unsafe)
// For now, we assume the pointer is managed externally
}
_ => {}
}
}
}