qtbridge_runtime/
qmetatype_compatible.rs1use std::cell::RefCell;
5use std::rc::Rc;
6
7use qtbridge_type_lib::{QList, QList_QString, QMetaType, QObject, QObjectList, QObjectMutPtr, QString};
8
9#[cfg(feature = "serde_json")]
10use qtbridge_type_lib::{QJsonArray, QJsonValue};
11
12use crate::{QMetaTypeGet, QObjectHolder, QmlElement};
13
14pub trait QMetaTypeCompatible {
24 type CompatibleType: QMetaTypeGet;
25
26 fn to_compatible(&self) -> Self::CompatibleType;
27 unsafe fn from_compatible(from: &Self::CompatibleType) -> Self;
35 fn compatible_qmetatype() -> QMetaType {
36 Self::CompatibleType::get_qmetatype()
37 }
38}
39
40macro_rules! impl_primitive_direct {
41 ($($t:ty),*) => {
42 $(impl QMetaTypeCompatible for $t {
43 type CompatibleType = $t;
44 fn to_compatible(&self) -> Self::CompatibleType { *self }
45 unsafe fn from_compatible(from: &Self::CompatibleType) -> Self { *from }
46 })*
47 }
48}
49impl_primitive_direct!(bool, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64);
50
51macro_rules! impl_primitive_convert {
52 ($($t:ty => $compat:ty),*) => {
53 $(impl QMetaTypeCompatible for $t {
54 type CompatibleType = $compat;
55 fn to_compatible(&self) -> Self::CompatibleType { *self as $compat }
56 unsafe fn from_compatible(from: &Self::CompatibleType) -> Self { *from as Self }
57 })*
58 }
59}
60#[cfg(target_pointer_width = "64")]
61impl_primitive_convert!(
62 isize => i64,
63 usize => u64
64);
65#[cfg(target_pointer_width = "32")]
66impl_primitive_convert!(
67 isize => i32,
68 usize => u32
69);
70
71macro_rules! impl_vec_direct {
76 ($($t:ty),*) => {
77 $(impl QMetaTypeCompatible for Vec<$t> {
78 type CompatibleType = QList<$t>;
79 fn to_compatible(&self) -> Self::CompatibleType { self.into_iter().collect() }
80 unsafe fn from_compatible(from: &Self::CompatibleType) -> Self { from.into() }
81 })*
82 }
83}
84impl_vec_direct!(bool, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64);
85
86macro_rules! impl_vec_convert {
87 ($($t:ty => $compat:ty),*) => {
88 $(impl QMetaTypeCompatible for Vec<$t> {
89 type CompatibleType = QList<$compat>;
90 fn to_compatible(&self) -> Self::CompatibleType {
91 self.iter()
92 .map(|arg| *arg as $compat)
93 .collect()
94 }
95 unsafe fn from_compatible(from: &Self::CompatibleType) -> Self {
96 from.iter()
97 .map(|arg| *arg as $t)
98 .collect()
99 }
100 })*
101 }
102}
103#[cfg(target_pointer_width = "64")]
104impl_vec_convert!(
105 isize => i64,
106 usize => u64
107);
108#[cfg(target_pointer_width = "32")]
109impl_vec_convert!(
110 isize => i32,
111 usize => u32
112);
113
114impl QMetaTypeCompatible for String {
115 type CompatibleType = QString;
116 fn to_compatible(&self) -> QString { self.into() }
117 unsafe fn from_compatible(from: &QString) -> String { from.into() }
118}
119
120impl QMetaTypeCompatible for Vec<String> {
121 type CompatibleType = QList_QString;
122
123 fn to_compatible(&self) -> Self::CompatibleType {
124 self.iter()
125 .map(QString::from)
126 .collect()
127 }
128
129 unsafe fn from_compatible(from: &Self::CompatibleType) -> Self {
130 from.iter()
131 .map(String::from)
132 .collect()
133 }
134}
135
136impl<T: QObjectHolder> QMetaTypeCompatible for Rc<RefCell<T>> {
137 type CompatibleType = *mut QObject;
138
139 fn to_compatible(&self) -> *mut QObject {
140 T::rc_ref_cell_to_qobject(self).cast_mut()
141 }
142
143 unsafe fn from_compatible(from: &*mut QObject) -> Self {
144 unsafe { T::qobject_to_rc_ref_cell(*from) }
145 }
146
147 fn compatible_qmetatype() -> QMetaType {
148 <T as QObjectHolder>::get_qobject_ptr_qmetatype()
149 }
150}
151
152impl<T: QmlElement> QMetaTypeCompatible for Vec<Rc<RefCell<T>>> {
154 type CompatibleType = QObjectList;
155
156 fn to_compatible(&self) -> QObjectList {
157 self.iter()
158 .map(|rc| unsafe { QObjectMutPtr::from_raw(T::rc_ref_cell_to_qobject(rc).cast_mut()) })
159 .collect()
160 }
161
162 unsafe fn from_compatible(from: &QObjectList) -> Self {
163 from.iter()
164 .map(|ptr| unsafe { T::qobject_to_rc_ref_cell(ptr.as_mut_ptr()) })
165 .collect()
166 }
167}
168
169#[cfg(feature = "serde_json")]
170impl QMetaTypeCompatible for serde_json::Value {
171 type CompatibleType = QJsonValue;
172 fn to_compatible(&self) -> QJsonValue { crate::serde_tools::serde_to_qjsonvalue(self) }
173 unsafe fn from_compatible(from: &QJsonValue) -> serde_json::Value { crate::serde_tools::qjsonvalue_to_serde(from) }
174}
175
176#[cfg(feature = "serde_json")]
177impl QMetaTypeCompatible for Vec<serde_json::Value> {
178 type CompatibleType = QJsonArray;
179 fn to_compatible(&self) -> QJsonArray { crate::serde_tools::serde_to_qjsonarray(self) }
180 unsafe fn from_compatible(from: &QJsonArray) -> Vec<serde_json::Value> {
181 from.iter()
182 .map(|jv| crate::serde_tools::qjsonvalue_to_serde(&jv))
183 .collect()
184 }
185}