1use std::cell::RefCell;
5use std::rc::Rc;
6
7use qtbridge_type_lib::{
8 QMetaType, QMetaTypeGet, QObject, QString, QVariant,
9 QList_bool, QList_i8, QList_u8, QList_i16, QList_u16,
10 QList_i32, QList_u32, QList_i64, QList_u64, QList_isize, QList_usize,
11 QList_f32, QList_f64, QList_QString,
12};
13
14#[cfg(feature = "serde_json")]
15use qtbridge_type_lib::{QJsonArray, QJsonValue};
16
17use crate::{QObjectHolder, QmlRegister};
18
19pub trait QPropertyMember: Sized {
30 fn qmetatype() -> QMetaType;
31
32 fn to_qvariant<Owner: QObjectHolder>(&self, owner: &Owner) -> QVariant;
37
38 fn to_qvariant_view<Owner, Notify>(&self, owner: &Owner, notify: Notify) -> QVariant
46 where
47 Owner: QObjectHolder,
48 Notify: Fn(&mut Owner) + 'static,
49 {
50 let _ = notify;
51 self.to_qvariant(owner)
52 }
53
54 fn from_qvariant(value: &QVariant) -> Result<Self, ()>;
56
57 fn property_eq(&self, other: &Self) -> bool;
61}
62
63macro_rules! impl_primitive {
64 ($($t:ty),*) => {
65 $(impl QPropertyMember for $t {
66 fn qmetatype() -> QMetaType { <$t as QMetaTypeGet>::get_qmetatype() }
67 fn to_qvariant<Owner: QObjectHolder>(&self, _owner: &Owner) -> QVariant { QVariant::from(self) }
68 fn from_qvariant(value: &QVariant) -> Result<Self, ()> { Self::try_from(value) }
69 fn property_eq(&self, other: &Self) -> bool { self == other }
70 })*
71 }
72}
73
74impl_primitive!(bool, i8, u8, i16, u16, i32, u32, i64, u64, isize, usize, f32, f64);
75
76macro_rules! impl_vec {
77 ($($t:ty => $qlist:ty),*) => {
78 $(impl QPropertyMember for Vec<$t> {
79 fn qmetatype() -> QMetaType { <$qlist as QMetaTypeGet>::get_qmetatype() }
80 fn to_qvariant<Owner: QObjectHolder>(&self, _owner: &Owner) -> QVariant { QVariant::from(self) }
81 fn from_qvariant(value: &QVariant) -> Result<Self, ()> { Self::try_from(value) }
82 fn property_eq(&self, other: &Self) -> bool { self == other }
83 })*
84 }
85}
86
87impl_vec!(
88 bool => QList_bool,
89 i8 => QList_i8,
90 u8 => QList_u8,
91 i16 => QList_i16,
92 u16 => QList_u16,
93 i32 => QList_i32,
94 u32 => QList_u32,
95 i64 => QList_i64,
96 u64 => QList_u64,
97 isize => QList_isize,
98 usize => QList_usize,
99 f32 => QList_f32,
100 f64 => QList_f64,
101 String => QList_QString
102);
103
104impl QPropertyMember for String {
105 fn qmetatype() -> QMetaType { <QString as QMetaTypeGet>::get_qmetatype() }
106 fn to_qvariant<Owner: QObjectHolder>(&self, _owner: &Owner) -> QVariant { QVariant::from(self) }
107 fn from_qvariant(value: &QVariant) -> Result<Self, ()> { Self::try_from(value) }
108 fn property_eq(&self, other: &Self) -> bool { self == other }
109}
110
111impl<T: QObjectHolder> QPropertyMember for Rc<RefCell<T>> {
112 fn qmetatype() -> QMetaType {
113 <*mut QObject as QMetaTypeGet>::get_qmetatype()
114 }
115
116 fn to_qvariant<Owner: QObjectHolder>(&self, _owner: &Owner) -> QVariant {
117 T::rc_ref_cell_to_qobject(self).cast_mut().into()
118 }
119
120 fn from_qvariant(value: &QVariant) -> Result<Self, ()> {
121 let ptr = <*mut QObject>::try_from(value)?;
122 Ok(unsafe { T::qobject_to_rc_ref_cell(ptr) })
123 }
124
125 fn property_eq(&self, other: &Self) -> bool {
126 Rc::ptr_eq(self, other)
127 }
128}
129
130impl<T: QmlRegister> QPropertyMember for Vec<Rc<RefCell<T>>> {
131 fn qmetatype() -> QMetaType {
132 T::get_list_qmetatype()
133 }
134
135 fn to_qvariant<Owner: QObjectHolder>(&self, owner: &Owner) -> QVariant {
136 T::list_to_qvariant(owner, self, |_: &mut Owner| {})
137 }
138
139 fn to_qvariant_view<Owner, Notify>(&self, owner: &Owner, notify: Notify) -> QVariant
140 where
141 Owner: QObjectHolder,
142 Notify: Fn(&mut Owner) + 'static,
143 {
144 T::list_to_qvariant(owner, self, notify)
145 }
146
147 fn from_qvariant(_value: &QVariant) -> Result<Self, ()> {
148 Err(())
150 }
151
152 fn property_eq(&self, other: &Self) -> bool {
153 self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| Rc::ptr_eq(a, b))
154 }
155}
156
157#[cfg(feature = "serde_json")]
158impl QPropertyMember for serde_json::Value {
159 fn qmetatype() -> QMetaType { <QJsonValue as QMetaTypeGet>::get_qmetatype() }
160 fn to_qvariant<Owner: QObjectHolder>(&self, _owner: &Owner) -> QVariant {
161 QVariant::from(&crate::serde_tools::serde_to_qjsonvalue(self))
162 }
163 fn from_qvariant(value: &QVariant) -> Result<Self, ()> {
164 crate::serde_tools::qvariant_to_serde(value)
165 }
166 fn property_eq(&self, other: &Self) -> bool { self == other }
167}
168
169#[cfg(feature = "serde_json")]
170impl QPropertyMember for Vec<serde_json::Value> {
171 fn qmetatype() -> QMetaType { <QJsonArray as QMetaTypeGet>::get_qmetatype() }
172 fn to_qvariant<Owner: QObjectHolder>(&self, _owner: &Owner) -> QVariant {
173 QVariant::from(&crate::serde_tools::serde_to_qjsonarray(self))
174 }
175 fn from_qvariant(value: &QVariant) -> Result<Self, ()> {
176 match crate::serde_tools::qvariant_to_serde(value)? {
177 serde_json::Value::Array(arr) => Ok(arr),
178 _ => Err(()),
179 }
180 }
181 fn property_eq(&self, other: &Self) -> bool { self == other }
182}
183
184#[doc(hidden)]
189pub fn get_meta_type_of_fn_return_value<F, This, R>(_f: F) -> QMetaType
190where
191 F: FnOnce(&This) -> &R,
192 R: QPropertyMember,
193{
194 R::qmetatype()
195}