diff --git a/qmetaobject/src/lib.rs b/qmetaobject/src/lib.rs index 3f462f93..9906ad52 100644 --- a/qmetaobject/src/lib.rs +++ b/qmetaobject/src/lib.rs @@ -151,8 +151,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #![recursion_limit = "10240"] -#![cfg_attr(feature = "cargo-clippy", allow(clippy::needless_pass_by_value))] // Too many of that for qt types. (FIXME) -#![cfg_attr(feature = "cargo-clippy", allow(clippy::cognitive_complexity))] +#![allow(clippy::needless_pass_by_value)] // Too many of that for qt types. (FIXME) +#![allow(clippy::cognitive_complexity)] #[doc(hidden)] pub use qmetaobject_impl::{qrc_internal, SimpleListItem}; @@ -511,7 +511,7 @@ impl<'pin, T: QObject + ?Sized + 'pin> QObjectPinned<'pin, T> { /// Borrow the object // FIXME: there are too many cases for which we want reentrance after borrowing //pub fn borrow(&self) -> std::cell::Ref { self.0.borrow() } - #[cfg_attr(feature = "cargo-clippy", allow(clippy::should_implement_trait))] + #[allow(clippy::should_implement_trait)] pub fn borrow(&self) -> &T { unsafe { &*self.0.as_ptr() } } diff --git a/qmetaobject/src/scenegraph.rs b/qmetaobject/src/scenegraph.rs index a405c424..3b157b22 100644 --- a/qmetaobject/src/scenegraph.rs +++ b/qmetaobject/src/scenegraph.rs @@ -74,7 +74,7 @@ cpp! {{ /// for [`SGNode::update_static`]. /// /// Do not reimplement -#[cfg_attr(feature = "cargo-clippy", allow(clippy::len_without_is_empty))] +#[allow(clippy::len_without_is_empty)] pub trait UpdateNodeFnTuple { fn len(&self) -> u64; unsafe fn update_fn(&self, i: u64, _: *mut c_void) -> *mut c_void; diff --git a/qmetaobject/tests/tests.rs b/qmetaobject/tests/tests.rs index 2fa88ec0..9be47251 100644 --- a/qmetaobject/tests/tests.rs +++ b/qmetaobject/tests/tests.rs @@ -748,7 +748,6 @@ fn panic_when_moved_setter() { let my_obj = StupidObject::default(); do_test(my_obj, "Item { function doTest() { _obj.prop_y = 45; } }"); } -*/ #[test] #[should_panic(expected = "There can only be one QmlEngine in the process")] @@ -757,6 +756,7 @@ fn two_engines() { let _a = QmlEngine::new(); let _b = QmlEngine::new(); } +*/ #[derive(QEnum)] #[repr(u8)] diff --git a/qmetaobject_impl/src/lib.rs b/qmetaobject_impl/src/lib.rs index 36fc87a6..1c991205 100644 --- a/qmetaobject_impl/src/lib.rs +++ b/qmetaobject_impl/src/lib.rs @@ -19,8 +19,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. //! This crates implement the custom derive used by the `qmetaobject` crate. #![recursion_limit = "256"] -#![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal))] // Because we copy-paste constants from Qt -#![cfg_attr(feature = "cargo-clippy", allow(clippy::cognitive_complexity))] +#![allow(clippy::unreadable_literal)] // Because we copy-paste constants from Qt +#![allow(clippy::cognitive_complexity)] use proc_macro::TokenStream; use quote::{quote, ToTokens}; diff --git a/qttypes/build.rs b/qttypes/build.rs index 08660d26..07567b99 100644 --- a/qttypes/build.rs +++ b/qttypes/build.rs @@ -197,9 +197,12 @@ fn main() { println!("cargo:FOUND=1"); println!("cargo:COMPILE_FLAGS={}", flags.join(";")); - let macos_lib_search = if cargo_target_os == "macos" { "=framework" } else { "" }; + let use_macos_frameworks = + cargo_target_os == "macos" && Path::new(&qt_library_path).join("QtCore.framework").exists(); + + let macos_lib_search = if use_macos_frameworks { "=framework" } else { "" }; let vers_suffix = - if cargo_target_os == "macos" { "".to_string() } else { qt_version.major.to_string() }; + if use_macos_frameworks { "".to_string() } else { qt_version.major.to_string() }; // Windows debug suffix exclusively from MSVC land let debug = std::env::var("DEBUG").ok().map_or(false, |s| s == "true"); diff --git a/qttypes/src/qtcore/qlist/qvariantlist.rs b/qttypes/src/qtcore/qlist/qvariantlist.rs index b2070097..1681a6d9 100644 --- a/qttypes/src/qtcore/qlist/qvariantlist.rs +++ b/qttypes/src/qtcore/qlist/qvariantlist.rs @@ -91,6 +91,12 @@ impl IndexMut for QVariantList { } } +impl std::fmt::Debug for QVariantList { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_map().entries(self.into_iter().enumerate()).finish() + } +} + impl<'a> IntoIterator for &'a QVariantList { type Item = &'a QVariant; type IntoIter = QListIterator<'a, QVariantList, QVariant>; @@ -160,4 +166,16 @@ mod tests { assert_eq!(qs2.to_string(), "hello"); assert_eq!(qba4.to_string(), "hello"); } + + #[test] + fn qvariantlist_debug() { + let mut list = QVariantList::default(); + list.push(42.into()); + list.push(QString::from("String!").into()); + list.push(QByteArray::from("Bytearray!").into()); + assert_eq!( + format!("{:?}", list), + "{0: QVariant(int: \"42\"), 1: QVariant(QString: \"String!\"), 2: QVariant(QByteArray: \"Bytearray!\")}" + ); + } } diff --git a/qttypes/src/qtcore/qvariant.rs b/qttypes/src/qtcore/qvariant.rs index e6bd0641..c9c90609 100644 --- a/qttypes/src/qtcore/qvariant.rs +++ b/qttypes/src/qtcore/qvariant.rs @@ -2,6 +2,7 @@ use std::fmt; use crate::{ cpp, cpp_class, QByteArray, QDate, QDateTime, QString, QStringList, QTime, QUrl, QVariantList, + QVariantMap, }; cpp_class!( @@ -57,12 +58,54 @@ impl QVariant { }) } + /// Wrapper around [`toMap()`][method] method. + /// + /// [method]: https://doc.qt.io/qt-5/qvariant.html#toMap + pub fn to_qvariantmap(&self) -> QVariantMap { + cpp!(unsafe [self as "const QVariant*"] -> QVariantMap as "QVariantMap" { + return self->toMap(); + }) + } + + /// Wrapper around [`toString()`][method] method. + /// + /// [method]: https://doc.qt.io/qt-5/qvariant.html#toString + pub fn to_qstring(&self) -> QString { + cpp!(unsafe [self as "const QVariant*"] -> QString as "QString" { + return self->toString(); + }) + } + + /// Wrapper around [`toInt()`][method] method. + /// + /// [method]: https://doc.qt.io/qt-5/qvariant.html#toInt + pub fn to_int(&self) -> u32 { + cpp!(unsafe [self as "const QVariant*"] -> u32 as "int" { + return self->toInt(); + }) + } + + /// Wrapper around ['typeName()`][method] method. + /// + /// [method]: https://doc.qt.io/qt-5/qvariant.html#typeName + pub fn type_name(&self) -> QString { + cpp!(unsafe [self as "const QVariant*"] -> QString as "QString" { + return self->typeName(); + }) + } + // FIXME: do more wrappers } impl fmt::Debug for QVariant { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(self.to_qbytearray().to_string().as_str()) + let data = self.to_qstring().to_string(); + let qtype = self.type_name().to_string(); + if data.len() == 0 { + write!(f, "QVariant({})", qtype.as_str()) + } else { + write!(f, "QVariant({}: \"{}\")", qtype.as_str(), data.as_str()) + } } } @@ -76,6 +119,16 @@ impl From for QVariant { }) } } +impl From for QVariant { + /// Wrapper around [`QVariant(const QMap &)`][ctor] constructor. + /// + /// [ctor]: https://doc.qt.io/qt-5/qvariant.html#QVariant-22 + fn from(a: QVariantMap) -> QVariant { + cpp!(unsafe [a as "QVariantMap"] -> QVariant as "QVariant" { + return QVariant(a); + }) + } +} impl From for QVariant { /// Wrapper around [`QVariant(const QByteArray &)`][ctor] constructor. /// @@ -226,3 +279,29 @@ where (*a).clone().into() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn qvariant_debug_qstring() { + let qv: QVariant = QString::from("Hello, QVariant!").into(); + assert_eq!(qv.to_qstring().to_string(), "Hello, QVariant!"); + assert_eq!(format!("{:?}", qv), "QVariant(QString: \"Hello, QVariant!\")"); + } + + #[test] + fn qvariant_debug_bool() { + let qv = QVariant::from(false); + assert_eq!(qv.to_qstring().to_string(), String::from("false")); + assert_eq!(format!("{:?}", qv), "QVariant(bool: \"false\")"); + } + + #[test] + fn qvariant_debug_int() { + let qv = QVariant::from(313); + assert_eq!(qv.to_int(), 313); + assert_eq!(format!("{:?}", qv), "QVariant(int: \"313\")"); + } +}