use cxx::{type_id, ExternType};
use std::mem::MaybeUninit;
#[cxx::bridge]
mod ffi {
unsafe extern "C++" {
include!("cxx-qt-lib/qvariant.h");
type QVariant = super::QVariant;
fn clear(self: &mut QVariant);
#[rust_name = "is_null"]
fn isNull(self: &QVariant) -> bool;
#[rust_name = "is_valid"]
fn isValid(self: &QVariant) -> bool;
}
#[namespace = "rust::cxxqtlib1"]
unsafe extern "C++" {
include!("cxx-qt-lib/common.h");
#[doc(hidden)]
#[rust_name = "qvariant_drop"]
fn drop(variant: &mut QVariant);
#[doc(hidden)]
#[rust_name = "qvariant_default"]
fn construct() -> QVariant;
#[doc(hidden)]
#[rust_name = "qvariant_clone"]
fn construct(variant: &QVariant) -> QVariant;
#[doc(hidden)]
#[rust_name = "qvariant_eq"]
fn operatorEq(a: &QVariant, b: &QVariant) -> bool;
}
}
#[repr(C)]
pub struct QVariant {
_data: MaybeUninit<f64>,
#[cfg(qt_version_major = "5")]
_type: MaybeUninit<u16>,
#[cfg(qt_version_major = "5")]
_is_shared: MaybeUninit<u16>,
#[cfg(qt_version_major = "5")]
_is_null: MaybeUninit<u16>,
#[cfg(qt_version_major = "6")]
_is_shared: MaybeUninit<usize>,
#[cfg(qt_version_major = "6")]
_is_null: MaybeUninit<usize>,
#[cfg(qt_version_major = "6")]
_packed_type: MaybeUninit<usize>,
}
impl Clone for QVariant {
fn clone(&self) -> Self {
ffi::qvariant_clone(self)
}
}
impl Default for QVariant {
fn default() -> Self {
ffi::qvariant_default()
}
}
impl Drop for QVariant {
fn drop(&mut self) {
ffi::qvariant_drop(self)
}
}
impl<T> From<&T> for QVariant
where
T: QVariantValue,
{
fn from(value: &T) -> Self {
T::construct(value)
}
}
impl QVariant {
pub fn value<T: QVariantValue>(&self) -> Option<T> {
if T::can_convert(self) {
Some(T::value_or_default(self))
} else {
None
}
}
pub fn value_or_default<T: QVariantValue>(&self) -> T {
T::value_or_default(self)
}
}
impl std::cmp::PartialEq for QVariant {
fn eq(&self, other: &Self) -> bool {
ffi::qvariant_eq(self, other)
}
}
pub trait QVariantValue {
fn can_convert(variant: &QVariant) -> bool;
fn construct(value: &Self) -> QVariant;
fn value_or_default(variant: &QVariant) -> Self;
}
macro_rules! impl_qvariant_value {
( $typeName:ty, $module:ident ) => {
mod $module;
impl QVariantValue for $typeName {
fn can_convert(variant: &QVariant) -> bool {
$module::can_convert(variant)
}
fn construct(value: &Self) -> QVariant {
$module::construct(value)
}
fn value_or_default(variant: &QVariant) -> Self {
$module::value_or_default(variant)
}
}
};
}
impl_qvariant_value!(bool, qvariant_bool);
impl_qvariant_value!(f32, qvariant_f32);
impl_qvariant_value!(f64, qvariant_f64);
impl_qvariant_value!(i8, qvariant_i8);
impl_qvariant_value!(i16, qvariant_i16);
impl_qvariant_value!(i32, qvariant_i32);
impl_qvariant_value!(i64, qvariant_i64);
impl_qvariant_value!(crate::QByteArray, qvariant_qbytearray);
#[cfg(feature = "qt_gui")]
impl_qvariant_value!(crate::QColor, qvariant_qcolor);
impl_qvariant_value!(crate::QDate, qvariant_qdate);
#[cfg(not(target_os = "emscripten"))]
impl_qvariant_value!(crate::QDateTime, qvariant_qdatetime);
impl_qvariant_value!(crate::QModelIndex, qvariant_qmodelindex);
impl_qvariant_value!(crate::QPersistentModelIndex, qvariant_qpersistentmodelindex);
impl_qvariant_value!(crate::QPoint, qvariant_qpoint);
impl_qvariant_value!(crate::QPointF, qvariant_qpointf);
impl_qvariant_value!(crate::QRect, qvariant_qrect);
impl_qvariant_value!(crate::QRectF, qvariant_qrectf);
impl_qvariant_value!(crate::QSize, qvariant_qsize);
impl_qvariant_value!(crate::QSizeF, qvariant_qsizef);
impl_qvariant_value!(crate::QString, qvariant_qstring);
impl_qvariant_value!(crate::QStringList, qvariant_qstringlist);
impl_qvariant_value!(crate::QTime, qvariant_qtime);
impl_qvariant_value!(crate::QUrl, qvariant_qurl);
impl_qvariant_value!(u8, qvariant_u8);
impl_qvariant_value!(u16, qvariant_u16);
impl_qvariant_value!(u32, qvariant_u32);
impl_qvariant_value!(u64, qvariant_u64);
unsafe impl ExternType for QVariant {
type Id = type_id!("QVariant");
type Kind = cxx::kind::Trivial;
}