diff --git a/README.md b/README.md index 831f60f03..aa08b08e3 100644 --- a/README.md +++ b/README.md @@ -34,21 +34,48 @@ For more complex examples navigate to the [examples folder](./examples) where th Below is an example of Rust code that exposes a QObject with two properties and four invokable methods to Qt. ```rust +use serde::{Deserialize, Serialize}; + +// Represent the Data struct below with serde friendly types, so we can (de)serialize it +#[derive(Deserialize, Serialize)] +pub struct DataSerde { + number: i32, + string: String, +} + +impl From for DataSerde { + fn from(value: Data) -> DataSerde { + DataSerde { + number: value.number, + string: value.string.to_string(), + } + } +} + #[cxx_qt::bridge] mod my_object { - use serde::{Deserialize, Serialize}; + use super::DataSerde; const DEFAULT_STR: &str = r#"{"number": 1, "string": "Hello World!"}"#; - #[derive(Deserialize, Serialize)] pub struct Data { - number: i32, - string: String, + pub number: i32, + pub string: UniquePtr, } impl Default for Data { fn default() -> Self { - serde_json::from_str(DEFAULT_STR).unwrap() + let data_serde: DataSerde = serde_json::from_str(DEFAULT_STR).unwrap(); + data_serde.into() + } + } + + impl From for Data { + fn from(value: DataSerde) -> Data { + Data { + number: value.number, + string: QString::from_str(&value.string), + } } } @@ -63,21 +90,23 @@ mod my_object { #[invokable] pub fn reset(&self, cpp: &mut CppObj) { - let data: Data = serde_json::from_str(DEFAULT_STR).unwrap(); - cpp.grab_values_from_data(data); + let data: DataSerde = serde_json::from_str(DEFAULT_STR).unwrap(); + cpp.grab_values_from_data(data.into()); } #[invokable] - pub fn serialize(&self, cpp: &mut CppObj) -> String { + pub fn serialize(&self, cpp: &mut CppObj) -> UniquePtr { let data = Data::from(cpp); - serde_json::to_string(&data).unwrap() + let data_serde = DataSerde::from(data); + let data_string = serde_json::to_string(&data_serde).unwrap(); + QString::from_str(&data_string) } #[invokable] pub fn grab_values(&self, cpp: &mut CppObj) { let string = r#"{"number": 2, "string": "Goodbye!"}"#; - let data: Data = serde_json::from_str(string).unwrap(); - cpp.grab_values_from_data(data); + let data: DataSerde = serde_json::from_str(string).unwrap(); + cpp.grab_values_from_data(data.into()); } } } diff --git a/book/src/concepts/types.md b/book/src/concepts/types.md index 86de44841..a592acd67 100644 --- a/book/src/concepts/types.md +++ b/book/src/concepts/types.md @@ -55,17 +55,15 @@ Note that when they are used as a parameter type in invokables they should be pa ### Custom Opaque Types -Custom opaque types wrap a unique pointer to the C++ type, they are used in the same way as custom trivial types but CXX-Qt automatically writes wrappers to convert to and from a C++ unique pointer of the type to a Rust wrapper of the type. +Custom [opaque types](https://en.wikipedia.org/wiki/Opaque_data_type) represent an opaque C++ type, they can be used for properties, parameters or return types in invokables, and parameters in signals. However when the object is being passed from Rust to C++ (eg properties, return types, or signals) they must be `UniquePtr`, and for other use cases they must be by reference (either `&T` or `Pin<&mut T>`). -On the rust side they appear as the cxx_qt_lib helper type. - -Note that when they are used as a parameter type in invokables they should be passed as a reference, eg `color: &QColor`, and when they are a property or return type they should be a value, eg `QColor`. Also for strings `&str` should be used when passed as a reference and `String` when passed as a value. +Note that when they are used as a parameter type in invokables they should be passed as a reference, eg `color: &QColor`, and when they are a property, return type, or signal they should be a `UniquePtr`, eg `UniquePtr`. | Rust Type | C++ Type | |-----------|----------| | cxx_qt_lib::QColor | QColor | | cxx_qt_lib::QDateTime | QDateTime | -| String or &str | QString | +| cxx_qt_lib::QString | QString | | cxx_qt_lib::QUrl | QUrl | | cxx_qt_lib::QVariant | QVariant | diff --git a/book/src/getting-started/2-our-first-cxx-qt-module.md b/book/src/getting-started/2-our-first-cxx-qt-module.md index c00f6994e..96481b30c 100644 --- a/book/src/getting-started/2-our-first-cxx-qt-module.md +++ b/book/src/getting-started/2-our-first-cxx-qt-module.md @@ -44,7 +44,7 @@ Note that the data types we use here are normal Rust data types. CXX-Qt will automatically convert these types to their C++/Qt equivalent. In our case that means: - `number: i32` -> `int number` -- `string: String` -> `QString string`\ +- `string: UniquePtr` -> `QString string`\ For more details on the available types, see the [Qt types page](../concepts/types.md). You might have also noticed the `#[derive(Default)]` here. diff --git a/cxx-qt-gen/src/extract.rs b/cxx-qt-gen/src/extract.rs index e697baf40..34029f26a 100644 --- a/cxx-qt-gen/src/extract.rs +++ b/cxx-qt-gen/src/extract.rs @@ -60,14 +60,16 @@ pub(crate) enum QtTypes { QRectF, QSize, QSizeF, - String, - Str, + QString, QTime, QUrl, QVariant, U8, U16, U32, + UniquePtr { + inner: Box, + }, Unknown, } @@ -84,11 +86,7 @@ impl QtTypes { pub(crate) fn is_opaque(&self) -> bool { match self { Self::CppObj { .. } => true, - Self::QColor => true, - Self::QDateTime => true, - Self::String | Self::Str => true, - Self::QUrl => true, - Self::QVariant => true, + Self::UniquePtr { .. } => true, _others => false, } } @@ -252,8 +250,7 @@ fn extract_qt_type( "QRectF" => Ok(QtTypes::QRectF), "QSize" => Ok(QtTypes::QSize), "QSizeF" => Ok(QtTypes::QSizeF), - "str" => Ok(QtTypes::Str), - "String" => Ok(QtTypes::String), + "QString" => Ok(QtTypes::QString), "QTime" => Ok(QtTypes::QTime), "QUrl" => Ok(QtTypes::QUrl), "QVariant" => Ok(QtTypes::QVariant), @@ -314,6 +311,16 @@ fn extract_qt_type( .to_case(Case::Pascal) ), }) + // This is a UniquePtr field + } else if idents.len() > 1 && idents.first().unwrap().to_string().as_str() == "UniquePtr" { + Ok(QtTypes::UniquePtr { + inner: Box::new(extract_qt_type( + &idents[1..], + original_ty, + cpp_namespace_prefix, + qt_ident, + )?), + }) // This is an unknown type that did not start with crate and has multiple parts } else { // We can assume that idents has an entry at index zero, because it is not empty @@ -323,6 +330,20 @@ fn extract_qt_type( /// Converts a given path to a vector of idents fn path_to_idents(path: &syn::Path) -> Result, ExtractTypeIdentError> { + // We do support UniquePtr for now + if let Some(segment) = path.segments.first() { + if segment.ident == "UniquePtr" { + if let PathArguments::AngleBracketed(angled) = &segment.arguments { + if let Some(GenericArgument::Type(Type::Path(type_path))) = angled.args.first() { + return path_to_idents(&type_path.path).map(|mut idents| { + idents.insert(0, quote::format_ident!("UniquePtr")); + idents + }); + } + } + } + } + path.segments .iter() .map(|segment| { @@ -331,10 +352,10 @@ fn path_to_idents(path: &syn::Path) -> Result, ExtractTypeIdentError> // eg we do not support AngleBracketed - the <'a, T> in std::slice::iter<'a, T> // eg we do not support Parenthesized - the (A, B) -> C in Fn(A, B) -> C if segment.arguments == PathArguments::None { - Ok(segment.ident.to_owned()) - } else { - Err(ExtractTypeIdentError::InvalidArguments(segment.span())) + return Ok(segment.ident.to_owned()); } + + Err(ExtractTypeIdentError::InvalidArguments(segment.span())) }) .collect::, ExtractTypeIdentError>>() } @@ -1485,8 +1506,9 @@ mod tests { let prop_second = &qobject.properties[1]; assert_eq!(prop_second.ident.cpp_ident.to_string(), "opaque"); assert_eq!(prop_second.ident.rust_ident.to_string(), "opaque"); - assert_eq!(prop_second.type_ident.idents.len(), 1); - assert_eq!(prop_second.type_ident.idents[0].to_string(), "QColor"); + assert_eq!(prop_second.type_ident.idents.len(), 2); + assert_eq!(prop_second.type_ident.idents[0].to_string(), "UniquePtr"); + assert_eq!(prop_second.type_ident.idents[1].to_string(), "QColor"); assert!(!prop_second.type_ident.is_ref); assert!(prop_second.getter.is_some()); @@ -1583,6 +1605,10 @@ mod tests { assert_eq!(qobject.signals[1].parameters[1].ident.to_string(), "second"); assert_eq!( qobject.signals[1].parameters[1].type_ident.idents[0].to_string(), + "UniquePtr" + ); + assert_eq!( + qobject.signals[1].parameters[1].type_ident.idents[1].to_string(), "QVariant" ); assert_eq!(qobject.signals[1].parameters[2].ident.to_string(), "third"); diff --git a/cxx-qt-gen/src/gen_cpp.rs b/cxx-qt-gen/src/gen_cpp.rs index 177d1ab97..199d79f08 100644 --- a/cxx-qt-gen/src/gen_cpp.rs +++ b/cxx-qt-gen/src/gen_cpp.rs @@ -90,10 +90,11 @@ impl CppType for QtTypes { Self::QRectF => vec!["#include ".to_owned()], Self::QSize => vec!["#include ".to_owned()], Self::QSizeF => vec!["#include ".to_owned()], - Self::String | Self::Str => vec!["#include ".to_owned()], + Self::QString => vec!["#include ".to_owned()], Self::QTime => vec!["#include ".to_owned()], Self::QUrl => vec!["#include ".to_owned()], Self::QVariant => vec!["#include ".to_owned()], + Self::UniquePtr { inner } => inner.include_paths(), _others => vec![], } } @@ -117,11 +118,12 @@ impl CppType for QtTypes { Self::QRectF => true, Self::QSize => true, Self::QSizeF => true, - Self::Str | Self::String => true, + Self::QString => true, Self::QTime => true, Self::QUrl => true, Self::QVariant => true, Self::U8 | Self::U16 | Self::U32 => false, + Self::UniquePtr { .. } => true, _other => unreachable!(), } } @@ -166,11 +168,12 @@ impl CppType for QtTypes { Self::QRectF => true, Self::QSize => true, Self::QSizeF => true, - Self::Str | Self::String => true, + Self::QString => true, Self::QTime => true, Self::QUrl => true, Self::QVariant => true, Self::U8 | Self::U16 | Self::U32 => false, + Self::UniquePtr { .. } => true, _other => unreachable!(), } } @@ -206,13 +209,19 @@ impl CppType for QtTypes { Self::QRectF => "QRectF", Self::QSize => "QSize", Self::QSizeF => "QSizeF", - Self::Str | Self::String => "QString", + Self::QString => "QString", Self::QTime => "QTime", Self::QUrl => "QUrl", Self::QVariant => "QVariant", Self::U8 => "quint8", Self::U16 => "quint16", Self::U32 => "quint32", + // TODO: for now always automatically convert UniquePtr to T + // in C++, later this will require a macro attribute to do this + // eg for properties, invokable returns, signals + // + // But this may be changed once the generation pattern matching has been removed + Self::UniquePtr { inner } => inner.type_ident(), _other => unreachable!(), } } diff --git a/cxx-qt-gen/src/gen_rs.rs b/cxx-qt-gen/src/gen_rs.rs index c9de248a9..ab388cc43 100644 --- a/cxx-qt-gen/src/gen_rs.rs +++ b/cxx-qt-gen/src/gen_rs.rs @@ -11,12 +11,6 @@ use std::collections::HashSet; use crate::extract::{Invokable, QObject, QtTypes}; use crate::utils::type_to_namespace; -/// The target type that we want, eg is this the QVariantCpp (Cpp) or QVariant (Rust) -enum TargetType { - Cpp, - Rust, -} - /// A trait which we implement on QtTypes allowing retrieval of attributes of the enum value. trait RustType { /// Whether this type is a reference @@ -24,7 +18,7 @@ trait RustType { /// The name of the type when defined in the CXX bridge, eg the A in type A = B; fn cxx_bridge_type_ident(&self) -> Ident; /// The full type for the parameter. Can be used Rust code outside cxx::bridge. - fn cxx_qt_lib_type(&self, target_type: TargetType) -> TokenStream; + fn cxx_qt_lib_type(&self) -> TokenStream; } impl RustType for QtTypes { @@ -41,9 +35,10 @@ impl RustType for QtTypes { Self::QSize => true, Self::QSizeF => true, Self::QTime => true, - Self::String | Self::Str => true, + Self::QString => true, Self::QUrl => true, Self::QVariant => true, + Self::UniquePtr { .. } => true, _others => false, } } @@ -69,20 +64,20 @@ impl RustType for QtTypes { Self::QRectF => format_ident!("QRectF"), Self::QSize => format_ident!("QSize"), Self::QSizeF => format_ident!("QSizeF"), - Self::Str => format_ident!("QString"), - Self::String => format_ident!("QString"), + Self::QString => format_ident!("QString"), Self::QTime => format_ident!("QTime"), Self::QUrl => format_ident!("QUrl"), Self::QVariant => format_ident!("QVariant"), Self::U8 => format_ident!("u8"), Self::U16 => format_ident!("u16"), Self::U32 => format_ident!("u32"), + Self::UniquePtr { inner } => format_ident!("{}", inner.cxx_bridge_type_ident()), _others => unreachable!(), } } /// The full type for the parameter. Can be used Rust code outside cxx::bridge. - fn cxx_qt_lib_type(&self, target_type: TargetType) -> TokenStream { + fn cxx_qt_lib_type(&self) -> TokenStream { match self { Self::Bool => quote! {bool}, Self::CppObj { @@ -95,41 +90,26 @@ impl RustType for QtTypes { Self::I8 => quote! {i8}, Self::I16 => quote! {i16}, Self::I32 => quote! {i32}, - Self::QColor => match target_type { - TargetType::Cpp => quote! {cxx_qt_lib::QColorCpp}, - TargetType::Rust => quote! {cxx_qt_lib::QColor}, - }, + Self::QColor => quote! {cxx_qt_lib::QColor}, Self::QDate => quote! {cxx_qt_lib::QDate}, - Self::QDateTime => match target_type { - TargetType::Cpp => quote! {cxx_qt_lib::QDateTimeCpp}, - TargetType::Rust => quote! {cxx_qt_lib::QDateTime}, - }, + Self::QDateTime => quote! {cxx_qt_lib::QDateTime}, Self::QPoint => quote! {cxx_qt_lib::QPoint}, Self::QPointF => quote! {cxx_qt_lib::QPointF}, Self::QRect => quote! {cxx_qt_lib::QRect}, Self::QRectF => quote! {cxx_qt_lib::QRectF}, Self::QSize => quote! {cxx_qt_lib::QSize}, Self::QSizeF => quote! {cxx_qt_lib::QSizeF}, - Self::Str => match target_type { - TargetType::Cpp => quote! {cxx_qt_lib::QStringCpp}, - TargetType::Rust => quote! {str}, - }, - Self::String => match target_type { - TargetType::Cpp => quote! {cxx_qt_lib::QStringCpp}, - TargetType::Rust => quote! {String}, - }, + Self::QString => quote! {cxx_qt_lib::QString}, Self::QTime => quote! {cxx_qt_lib::QTime}, - Self::QUrl => match target_type { - TargetType::Cpp => quote! {cxx_qt_lib::QUrlCpp}, - TargetType::Rust => quote! {cxx_qt_lib::QUrl}, - }, - Self::QVariant => match target_type { - TargetType::Cpp => quote! {cxx_qt_lib::QVariantCpp}, - TargetType::Rust => quote! {cxx_qt_lib::QVariant}, - }, + Self::QUrl => quote! {cxx_qt_lib::QUrl}, + Self::QVariant => quote! {cxx_qt_lib::QVariant}, Self::U8 => quote! {u8}, Self::U16 => quote! {u16}, Self::U32 => quote! {u32}, + Self::UniquePtr { inner } => { + let inner = inner.cxx_qt_lib_type(); + quote! {UniquePtr<#inner>} + } _other => unreachable!(), } } @@ -528,7 +508,7 @@ pub fn generate_qobject_cxx( // Build the import path for the C++ header let import_path = format!("cxx-qt-gen/include/{}.cxxqt.h", ident_snake); - // TODO: ideally we only want to add the "type QString = cxx_qt_lib::QStringCpp;" + // TODO: ideally we only want to add the "type QString = cxx_qt_lib::QString;" // if we actually generate some code that uses QString. // Build the namespace string, rust::module @@ -555,11 +535,11 @@ pub fn generate_qobject_cxx( include!("cxx-qt-lib/include/qt_types.h"); #[namespace = ""] - type QColor = cxx_qt_lib::QColorCpp; + type QColor = cxx_qt_lib::QColor; #[namespace = ""] type QDate = cxx_qt_lib::QDate; #[namespace = ""] - type QDateTime = cxx_qt_lib::QDateTimeCpp; + type QDateTime = cxx_qt_lib::QDateTime; #[namespace = ""] type QPoint = cxx_qt_lib::QPoint; #[namespace = ""] @@ -573,13 +553,13 @@ pub fn generate_qobject_cxx( #[namespace = ""] type QSizeF = cxx_qt_lib::QSizeF; #[namespace = ""] - type QString = cxx_qt_lib::QStringCpp; + type QString = cxx_qt_lib::QString; #[namespace = ""] type QTime = cxx_qt_lib::QTime; #[namespace = ""] - type QUrl = cxx_qt_lib::QUrlCpp; + type QUrl = cxx_qt_lib::QUrl; #[namespace = ""] - type QVariant = cxx_qt_lib::QVariantCpp; + type QVariant = cxx_qt_lib::QVariant; #update_requester_type #(#cpp_functions)* @@ -632,8 +612,12 @@ fn generate_property_methods_rs(obj: &QObject) -> Result, Token let mut property_methods = Vec::new(); for property in &obj.properties { - let qt_type = &property.type_ident.qt_type; - let rust_param_type = qt_type.cxx_qt_lib_type(TargetType::Rust); + let qt_type = if let QtTypes::UniquePtr { inner } = &property.type_ident.qt_type { + &**inner + } else { + &property.type_ident.qt_type + }; + let rust_param_type = qt_type.cxx_qt_lib_type(); // When the output type is opaque we pass by value rather than ref // even though it's a non trivial type let rust_param_type = if !qt_type.is_opaque() && qt_type.is_ref() { @@ -665,16 +649,10 @@ fn generate_property_methods_rs(obj: &QObject) -> Result, Token if let Some(getter) = &property.getter { // Generate a getter using the rust ident let getter_ident = &getter.rust_ident; - // If the type is opaque then we need to convert to the Rust form - let opaque_converter = if qt_type.is_opaque() { - quote! {.to_rust()} - } else { - quote! {} - }; property_methods.push(quote! { pub fn #getter_ident(&self) -> #rust_param_type { - self.cpp.#cpp_getter_ident()#opaque_converter + self.cpp.#cpp_getter_ident() } }); } @@ -683,18 +661,9 @@ fn generate_property_methods_rs(obj: &QObject) -> Result, Token // Generate a setter using the rust ident let setter_ident = &setter.rust_ident; if qt_type.is_opaque() { - // Special case where instead of generating &String - // we use &str as the input for setter methods. - // - // FIXME: can we make this generic in the RustType trait somewhere? - let rust_param_type = match qt_type { - QtTypes::String => quote! {&str}, - _others => rust_param_type, - }; - property_methods.push(quote! { pub fn #setter_ident(&mut self, value: #rust_param_type) { - self.cpp.as_mut().#cpp_setter_ident(&value.to_unique_ptr()); + self.cpp.as_mut().#cpp_setter_ident(&value); } }); } else { @@ -730,9 +699,8 @@ fn generate_signal_methods_rs(obj: &QObject) -> Result, TokenSt .iter() .map(|parameter| { let ident = ¶meter.ident; - if parameter.type_ident.qt_type.is_opaque() { - quote! { &#ident.to_unique_ptr() } - } else if parameter.type_ident.qt_type.is_ref() { + if parameter.type_ident.qt_type.is_opaque() || parameter.type_ident.qt_type.is_ref() + { quote! { &#ident } } else { ident.into_token_stream() @@ -745,7 +713,7 @@ fn generate_signal_methods_rs(obj: &QObject) -> Result, TokenSt .map(|parameter| { let ident = ¶meter.ident; if parameter.type_ident.qt_type.is_opaque() { - quote! { #ident.to_unique_ptr() } + quote! { #ident } } else { ident.into_token_stream() } @@ -883,27 +851,19 @@ fn invokable_generate_wrapper( output_parameters.push(quote! { #param_ident }); } - let param_type = param.type_ident.qt_type.cxx_qt_lib_type(TargetType::Cpp); + let param_type = param.type_ident.qt_type.cxx_qt_lib_type(); input_parameters.push(quote! { #param_ident: #is_ref #is_mut #param_type }); } } // If we are an opaque return type then we need to convert into the C++ type if let Some(return_type) = &invokable.return_type { - let return_type_ident = return_type.qt_type.cxx_qt_lib_type(TargetType::Cpp); - let (return_type_ident, to_unique_ptr) = if return_type.qt_type.is_opaque() { - ( - quote! {cxx::UniquePtr<#return_type_ident>}, - quote! { .to_unique_ptr() }, - ) - } else { - (return_type_ident, quote! {}) - }; + let return_type_ident = return_type.qt_type.cxx_qt_lib_type(); Ok(quote! { pub fn #ident_wrapper(&#mutablility self, #(#input_parameters),*) -> #return_type_ident { #(#wrappers)* - return self.#ident(#(#output_parameters),*)#to_unique_ptr; + return self.#ident(#(#output_parameters),*); } }) } else { @@ -1098,9 +1058,9 @@ pub fn generate_qobject_rs( let field_name = field_ident.clone(); let setter_name = format_ident!("set_{}", field_name); - if qt_type.is_opaque() && !matches!(qt_type, QtTypes::String | QtTypes::Str) { + if qt_type.is_opaque() { grab_values.push(quote! { - self.#setter_name(std::mem::take(&mut data.#field_name)); + self.#setter_name(data.#field_name.as_ref().unwrap()); }); } else { let is_ref = if qt_type.is_ref() { @@ -1147,8 +1107,6 @@ pub fn generate_qobject_rs( if obj.handle_updates_impl.is_some() { use_traits.push(quote! { use cxx_qt_lib::UpdateRequestHandler; }); } - // TODO: only push if we have an opaque param or return type? - use_traits.push(quote! { use cxx_qt_lib::ToUniquePtr; }); let handle_updates_impl = &obj.handle_updates_impl; @@ -1167,6 +1125,7 @@ pub fn generate_qobject_rs( #(#use_traits)* pub type FFICppObj = super::#mod_ident::#class_name_cpp; + type UniquePtr = cxx::UniquePtr; #(#original_passthrough_decls)* diff --git a/cxx-qt-gen/test_inputs/handlers.rs b/cxx-qt-gen/test_inputs/handlers.rs index ca0ebda7e..c520f2203 100644 --- a/cxx-qt-gen/test_inputs/handlers.rs +++ b/cxx-qt-gen/test_inputs/handlers.rs @@ -2,7 +2,7 @@ mod my_object { #[derive(Default)] pub struct Data { number: i32, - string: String, + string: QString, } #[derive(Default)] diff --git a/cxx-qt-gen/test_inputs/invokables.rs b/cxx-qt-gen/test_inputs/invokables.rs index fd9e58950..bbd890a30 100644 --- a/cxx-qt-gen/test_inputs/invokables.rs +++ b/cxx-qt-gen/test_inputs/invokables.rs @@ -46,7 +46,7 @@ mod my_object { } #[invokable] - pub fn invokable_return_opaque(&mut self) -> QColor { + pub fn invokable_return_opaque(&mut self) -> UniquePtr { cxx_qt_lib::QColor::from_rgba(255, 0, 0, 0) } @@ -56,8 +56,8 @@ mod my_object { } #[invokable] - pub fn invokable_return_static(&mut self) -> &str { - "static" + pub fn invokable_return_static(&mut self) -> UniquePtr { + QString::from_str("static") } pub fn rust_only_method(&self) { diff --git a/cxx-qt-gen/test_inputs/properties.rs b/cxx-qt-gen/test_inputs/properties.rs index 29e9acb64..857b56d0a 100644 --- a/cxx-qt-gen/test_inputs/properties.rs +++ b/cxx-qt-gen/test_inputs/properties.rs @@ -4,7 +4,7 @@ mod my_object { #[derive(Default)] pub struct Data { primitive: i32, - opaque: QColor, + opaque: UniquePtr, nested: crate::cxx_qt_nested_object::CppObj, } diff --git a/cxx-qt-gen/test_inputs/signals.rs b/cxx-qt-gen/test_inputs/signals.rs index a04d8bac7..9a34a2715 100644 --- a/cxx-qt-gen/test_inputs/signals.rs +++ b/cxx-qt-gen/test_inputs/signals.rs @@ -6,7 +6,7 @@ mod my_object { Ready, DataChanged { first: i32, - second: QVariant, + second: UniquePtr, third: QPoint, }, } diff --git a/cxx-qt-gen/test_inputs/types_qt_invokable.rs b/cxx-qt-gen/test_inputs/types_qt_invokable.rs index d91e6665a..493656304 100644 --- a/cxx-qt-gen/test_inputs/types_qt_invokable.rs +++ b/cxx-qt-gen/test_inputs/types_qt_invokable.rs @@ -7,7 +7,7 @@ mod my_object { impl RustObj { #[invokable] - pub fn test_color(&self, _cpp: &mut CppObj, color: &QColor) -> QColor { + pub fn test_color(&self, _cpp: &mut CppObj, color: &QColor) -> UniquePtr { color } @@ -17,7 +17,11 @@ mod my_object { } #[invokable] - pub fn test_date_time(&self, _cpp: &mut CppObj, dateTime: &QDateTime) -> QDateTime { + pub fn test_date_time( + &self, + _cpp: &mut CppObj, + dateTime: &QDateTime, + ) -> UniquePtr { dateTime } @@ -52,7 +56,7 @@ mod my_object { } #[invokable] - pub fn test_string(&self, _cpp: &mut CppObj, string: &str) -> String { + pub fn test_string(&self, _cpp: &mut CppObj, string: &QString) -> UniquePtr { string.to_owned() } @@ -62,12 +66,12 @@ mod my_object { } #[invokable] - pub fn test_url(&self, _cpp: &mut CppObj, url: &QUrl) -> QUrl { + pub fn test_url(&self, _cpp: &mut CppObj, url: &QUrl) -> UniquePtr { url } #[invokable] - pub fn test_variant(&self, _cpp: &mut CppObj, variant: &QVariant) -> QVariant { + pub fn test_variant(&self, _cpp: &mut CppObj, variant: &QVariant) -> UniquePtr { variant } } diff --git a/cxx-qt-gen/test_inputs/types_qt_property.rs b/cxx-qt-gen/test_inputs/types_qt_property.rs index 76fba4945..a7a4876f9 100644 --- a/cxx-qt-gen/test_inputs/types_qt_property.rs +++ b/cxx-qt-gen/test_inputs/types_qt_property.rs @@ -1,19 +1,19 @@ mod my_object { #[derive(Default)] pub struct Data { - color: QColor, + color: UniquePtr, date: QDate, - date_time: QDateTime, + date_time: UniquePtr, point: QPoint, pointf: QPointF, rect: QRect, rectf: QRectF, size: QSize, sizef: QSizeF, - string: String, + string: UniquePtr, time: QTime, - url: QUrl, - variant: QVariant, + url: UniquePtr, + variant: UniquePtr, } #[derive(Default)] diff --git a/cxx-qt-gen/test_outputs/custom_default.rs b/cxx-qt-gen/test_outputs/custom_default.rs index 0a30fe701..342b62356 100644 --- a/cxx-qt-gen/test_outputs/custom_default.rs +++ b/cxx-qt-gen/test_outputs/custom_default.rs @@ -8,11 +8,11 @@ mod my_object { include!("cxx-qt-lib/include/qt_types.h"); #[namespace = ""] - type QColor = cxx_qt_lib::QColorCpp; + type QColor = cxx_qt_lib::QColor; #[namespace = ""] type QDate = cxx_qt_lib::QDate; #[namespace = ""] - type QDateTime = cxx_qt_lib::QDateTimeCpp; + type QDateTime = cxx_qt_lib::QDateTime; #[namespace = ""] type QPoint = cxx_qt_lib::QPoint; #[namespace = ""] @@ -26,13 +26,13 @@ mod my_object { #[namespace = ""] type QSizeF = cxx_qt_lib::QSizeF; #[namespace = ""] - type QString = cxx_qt_lib::QStringCpp; + type QString = cxx_qt_lib::QString; #[namespace = ""] type QTime = cxx_qt_lib::QTime; #[namespace = ""] - type QUrl = cxx_qt_lib::QUrlCpp; + type QUrl = cxx_qt_lib::QUrl; #[namespace = ""] - type QVariant = cxx_qt_lib::QVariantCpp; + type QVariant = cxx_qt_lib::QVariant; #[rust_name = "public"] fn getPublic(self: &MyObjectQt) -> i32; @@ -59,9 +59,8 @@ pub use self::cxx_qt_my_object::*; mod cxx_qt_my_object { use super::my_object::*; - use cxx_qt_lib::ToUniquePtr; - pub type FFICppObj = super::my_object::MyObjectQt; + type UniquePtr = cxx::UniquePtr; pub struct RustObj { private: i32, diff --git a/cxx-qt-gen/test_outputs/handlers.rs b/cxx-qt-gen/test_outputs/handlers.rs index acee035a1..2d9b722ef 100644 --- a/cxx-qt-gen/test_outputs/handlers.rs +++ b/cxx-qt-gen/test_outputs/handlers.rs @@ -8,11 +8,11 @@ mod my_object { include!("cxx-qt-lib/include/qt_types.h"); #[namespace = ""] - type QColor = cxx_qt_lib::QColorCpp; + type QColor = cxx_qt_lib::QColor; #[namespace = ""] type QDate = cxx_qt_lib::QDate; #[namespace = ""] - type QDateTime = cxx_qt_lib::QDateTimeCpp; + type QDateTime = cxx_qt_lib::QDateTime; #[namespace = ""] type QPoint = cxx_qt_lib::QPoint; #[namespace = ""] @@ -26,13 +26,13 @@ mod my_object { #[namespace = ""] type QSizeF = cxx_qt_lib::QSizeF; #[namespace = ""] - type QString = cxx_qt_lib::QStringCpp; + type QString = cxx_qt_lib::QString; #[namespace = ""] type QTime = cxx_qt_lib::QTime; #[namespace = ""] - type QUrl = cxx_qt_lib::QUrlCpp; + type QUrl = cxx_qt_lib::QUrl; #[namespace = ""] - type QVariant = cxx_qt_lib::QVariantCpp; + type QVariant = cxx_qt_lib::QVariant; #[namespace = "rust::cxxqtlib1"] type UpdateRequester = cxx_qt_lib::UpdateRequesterCpp; @@ -73,10 +73,10 @@ pub use self::cxx_qt_my_object::*; mod cxx_qt_my_object { use super::my_object::*; - use cxx_qt_lib::ToUniquePtr; use cxx_qt_lib::UpdateRequestHandler; pub type FFICppObj = super::my_object::MyObjectQt; + type UniquePtr = cxx::UniquePtr; #[derive(Default)] pub struct RustObj; @@ -105,12 +105,12 @@ mod cxx_qt_my_object { self.cpp.as_mut().set_number(value); } - pub fn string(&self) -> String { - self.cpp.string().to_rust() + pub fn string(&self) -> &cxx_qt_lib::QString { + self.cpp.string() } - pub fn set_string(&mut self, value: &str) { - self.cpp.as_mut().set_string(&value.to_unique_ptr()); + pub fn set_string(&mut self, value: &cxx_qt_lib::QString) { + self.cpp.as_mut().set_string(value); } pub fn update_requester(&mut self) -> cxx_qt_lib::UpdateRequester { @@ -126,7 +126,7 @@ mod cxx_qt_my_object { #[derive(Default)] pub struct Data { number: i32, - string: String, + string: QString, } impl<'a> From<&CppObj<'a>> for Data { diff --git a/cxx-qt-gen/test_outputs/invokables.cpp b/cxx-qt-gen/test_outputs/invokables.cpp index 9e1273456..17c524dd1 100644 --- a/cxx-qt-gen/test_outputs/invokables.cpp +++ b/cxx-qt-gen/test_outputs/invokables.cpp @@ -54,7 +54,7 @@ MyObject::invokableParameters(const QColor& opaque, qint32 primitive) { const std::lock_guard guard(m_rustObjMutex); - m_rustObj->invokableParametersWrapper(opaque, trivial, primitive); + m_rustObj->invokableParameters(opaque, trivial, primitive); } void diff --git a/cxx-qt-gen/test_outputs/invokables.rs b/cxx-qt-gen/test_outputs/invokables.rs index c0244f1d7..2db2b7772 100644 --- a/cxx-qt-gen/test_outputs/invokables.rs +++ b/cxx-qt-gen/test_outputs/invokables.rs @@ -8,11 +8,11 @@ mod my_object { include!("cxx-qt-lib/include/qt_types.h"); #[namespace = ""] - type QColor = cxx_qt_lib::QColorCpp; + type QColor = cxx_qt_lib::QColor; #[namespace = ""] type QDate = cxx_qt_lib::QDate; #[namespace = ""] - type QDateTime = cxx_qt_lib::QDateTimeCpp; + type QDateTime = cxx_qt_lib::QDateTime; #[namespace = ""] type QPoint = cxx_qt_lib::QPoint; #[namespace = ""] @@ -26,13 +26,13 @@ mod my_object { #[namespace = ""] type QSizeF = cxx_qt_lib::QSizeF; #[namespace = ""] - type QString = cxx_qt_lib::QStringCpp; + type QString = cxx_qt_lib::QString; #[namespace = ""] type QTime = cxx_qt_lib::QTime; #[namespace = ""] - type QUrl = cxx_qt_lib::QUrlCpp; + type QUrl = cxx_qt_lib::QUrl; #[namespace = ""] - type QVariant = cxx_qt_lib::QVariantCpp; + type QVariant = cxx_qt_lib::QVariant; #[namespace = "cxx_qt::nested_object"] type NestedObject = crate::cxx_qt_nested_object::FFICppObj; @@ -55,13 +55,8 @@ mod my_object { fn invokable_mutable_cpp_obj_wrapper(self: &mut RustObj, cpp: Pin<&mut MyObjectQt>); #[cxx_name = "invokableNestedParameterWrapper"] fn invokable_nested_parameter_wrapper(self: &RustObj, nested: Pin<&mut NestedObject>); - #[cxx_name = "invokableParametersWrapper"] - fn invokable_parameters_wrapper( - self: &RustObj, - opaque: &QColor, - trivial: &QPoint, - primitive: i32, - ); + #[cxx_name = "invokableParameters"] + fn invokable_parameters(self: &RustObj, opaque: &QColor, trivial: &QPoint, primitive: i32); #[cxx_name = "invokableParametersCppObjWrapper"] fn invokable_parameters_cpp_obj_wrapper( self: &RustObj, @@ -87,9 +82,8 @@ pub use self::cxx_qt_my_object::*; mod cxx_qt_my_object { use super::my_object::*; - use cxx_qt_lib::ToUniquePtr; - pub type FFICppObj = super::my_object::MyObjectQt; + type UniquePtr = cxx::UniquePtr; use cxx_qt_lib::QColor; @@ -115,16 +109,6 @@ mod cxx_qt_my_object { self.invokable_nested_parameter(&mut nested); } - pub fn invokable_parameters_wrapper( - &self, - opaque: &cxx_qt_lib::QColorCpp, - trivial: &cxx_qt_lib::QPoint, - primitive: i32, - ) { - let opaque = opaque.to_rust(); - self.invokable_parameters(&opaque, trivial, primitive); - } - pub fn invokable_parameters_cpp_obj_wrapper( &self, primitive: i32, @@ -134,14 +118,12 @@ mod cxx_qt_my_object { self.invokable_parameters_cpp_obj(primitive, &mut cpp); } - pub fn invokable_return_opaque_wrapper(&mut self) -> cxx::UniquePtr { - return self.invokable_return_opaque().to_unique_ptr(); + pub fn invokable_return_opaque_wrapper(&mut self) -> UniquePtr { + return self.invokable_return_opaque(); } - pub fn invokable_return_static_wrapper( - &mut self, - ) -> cxx::UniquePtr { - return self.invokable_return_static().to_unique_ptr(); + pub fn invokable_return_static_wrapper(&mut self) -> UniquePtr { + return self.invokable_return_static(); } pub fn invokable(&self) { @@ -177,7 +159,7 @@ mod cxx_qt_my_object { println!("{}", primitive); } - pub fn invokable_return_opaque(&mut self) -> QColor { + pub fn invokable_return_opaque(&mut self) -> UniquePtr { cxx_qt_lib::QColor::from_rgba(255, 0, 0, 0) } @@ -185,8 +167,8 @@ mod cxx_qt_my_object { 2 } - pub fn invokable_return_static(&mut self) -> &str { - "static" + pub fn invokable_return_static(&mut self) -> UniquePtr { + QString::from_str("static") } pub fn rust_only_method(&self) { diff --git a/cxx-qt-gen/test_outputs/naming.rs b/cxx-qt-gen/test_outputs/naming.rs index fe9d07f2f..cce145263 100644 --- a/cxx-qt-gen/test_outputs/naming.rs +++ b/cxx-qt-gen/test_outputs/naming.rs @@ -8,11 +8,11 @@ mod my_object { include!("cxx-qt-lib/include/qt_types.h"); #[namespace = ""] - type QColor = cxx_qt_lib::QColorCpp; + type QColor = cxx_qt_lib::QColor; #[namespace = ""] type QDate = cxx_qt_lib::QDate; #[namespace = ""] - type QDateTime = cxx_qt_lib::QDateTimeCpp; + type QDateTime = cxx_qt_lib::QDateTime; #[namespace = ""] type QPoint = cxx_qt_lib::QPoint; #[namespace = ""] @@ -26,13 +26,13 @@ mod my_object { #[namespace = ""] type QSizeF = cxx_qt_lib::QSizeF; #[namespace = ""] - type QString = cxx_qt_lib::QStringCpp; + type QString = cxx_qt_lib::QString; #[namespace = ""] type QTime = cxx_qt_lib::QTime; #[namespace = ""] - type QUrl = cxx_qt_lib::QUrlCpp; + type QUrl = cxx_qt_lib::QUrl; #[namespace = ""] - type QVariant = cxx_qt_lib::QVariantCpp; + type QVariant = cxx_qt_lib::QVariant; #[rust_name = "property_name"] fn getPropertyName(self: &MyObjectQt) -> i32; @@ -62,9 +62,8 @@ pub use self::cxx_qt_my_object::*; mod cxx_qt_my_object { use super::my_object::*; - use cxx_qt_lib::ToUniquePtr; - pub type FFICppObj = super::my_object::MyObjectQt; + type UniquePtr = cxx::UniquePtr; #[derive(Default)] pub struct RustObj; diff --git a/cxx-qt-gen/test_outputs/passthrough.rs b/cxx-qt-gen/test_outputs/passthrough.rs index 78b50cd97..699036455 100644 --- a/cxx-qt-gen/test_outputs/passthrough.rs +++ b/cxx-qt-gen/test_outputs/passthrough.rs @@ -8,11 +8,11 @@ pub mod my_object { include!("cxx-qt-lib/include/qt_types.h"); #[namespace = ""] - type QColor = cxx_qt_lib::QColorCpp; + type QColor = cxx_qt_lib::QColor; #[namespace = ""] type QDate = cxx_qt_lib::QDate; #[namespace = ""] - type QDateTime = cxx_qt_lib::QDateTimeCpp; + type QDateTime = cxx_qt_lib::QDateTime; #[namespace = ""] type QPoint = cxx_qt_lib::QPoint; #[namespace = ""] @@ -26,13 +26,13 @@ pub mod my_object { #[namespace = ""] type QSizeF = cxx_qt_lib::QSizeF; #[namespace = ""] - type QString = cxx_qt_lib::QStringCpp; + type QString = cxx_qt_lib::QString; #[namespace = ""] type QTime = cxx_qt_lib::QTime; #[namespace = ""] - type QUrl = cxx_qt_lib::QUrlCpp; + type QUrl = cxx_qt_lib::QUrl; #[namespace = ""] - type QVariant = cxx_qt_lib::QVariantCpp; + type QVariant = cxx_qt_lib::QVariant; #[rust_name = "number"] fn getNumber(self: &MyObjectQt) -> i32; @@ -79,9 +79,8 @@ pub use self::cxx_qt_my_object::*; pub mod cxx_qt_my_object { use super::my_object::*; - use cxx_qt_lib::ToUniquePtr; - pub type FFICppObj = super::my_object::MyObjectQt; + type UniquePtr = cxx::UniquePtr; const MAX: u16 = 65535; diff --git a/cxx-qt-gen/test_outputs/properties.rs b/cxx-qt-gen/test_outputs/properties.rs index 30698b4dd..cd8b59828 100644 --- a/cxx-qt-gen/test_outputs/properties.rs +++ b/cxx-qt-gen/test_outputs/properties.rs @@ -8,11 +8,11 @@ mod my_object { include!("cxx-qt-lib/include/qt_types.h"); #[namespace = ""] - type QColor = cxx_qt_lib::QColorCpp; + type QColor = cxx_qt_lib::QColor; #[namespace = ""] type QDate = cxx_qt_lib::QDate; #[namespace = ""] - type QDateTime = cxx_qt_lib::QDateTimeCpp; + type QDateTime = cxx_qt_lib::QDateTime; #[namespace = ""] type QPoint = cxx_qt_lib::QPoint; #[namespace = ""] @@ -26,13 +26,13 @@ mod my_object { #[namespace = ""] type QSizeF = cxx_qt_lib::QSizeF; #[namespace = ""] - type QString = cxx_qt_lib::QStringCpp; + type QString = cxx_qt_lib::QString; #[namespace = ""] type QTime = cxx_qt_lib::QTime; #[namespace = ""] - type QUrl = cxx_qt_lib::QUrlCpp; + type QUrl = cxx_qt_lib::QUrl; #[namespace = ""] - type QVariant = cxx_qt_lib::QVariantCpp; + type QVariant = cxx_qt_lib::QVariant; #[rust_name = "primitive"] fn getPrimitive(self: &MyObjectQt) -> i32; @@ -72,9 +72,8 @@ pub use self::cxx_qt_my_object::*; mod cxx_qt_my_object { use super::my_object::*; - use cxx_qt_lib::ToUniquePtr; - pub type FFICppObj = super::my_object::MyObjectQt; + type UniquePtr = cxx::UniquePtr; use cxx_qt_lib::QColor; @@ -100,12 +99,12 @@ mod cxx_qt_my_object { self.cpp.as_mut().set_primitive(value); } - pub fn opaque(&self) -> cxx_qt_lib::QColor { - self.cpp.opaque().to_rust() + pub fn opaque(&self) -> &cxx_qt_lib::QColor { + self.cpp.opaque() } - pub fn set_opaque(&mut self, value: cxx_qt_lib::QColor) { - self.cpp.as_mut().set_opaque(&value.to_unique_ptr()); + pub fn set_opaque(&mut self, value: &cxx_qt_lib::QColor) { + self.cpp.as_mut().set_opaque(value); } pub fn take_nested(&mut self) -> cxx::UniquePtr { @@ -118,14 +117,14 @@ mod cxx_qt_my_object { pub fn grab_values_from_data(&mut self, mut data: Data) { self.set_primitive(data.primitive); - self.set_opaque(std::mem::take(&mut data.opaque)); + self.set_opaque(data.opaque.as_ref().unwrap()); } } #[derive(Default)] pub struct Data { primitive: i32, - opaque: QColor, + opaque: UniquePtr, } impl<'a> From<&CppObj<'a>> for Data { diff --git a/cxx-qt-gen/test_outputs/signals.rs b/cxx-qt-gen/test_outputs/signals.rs index 0463372e5..358d0edde 100644 --- a/cxx-qt-gen/test_outputs/signals.rs +++ b/cxx-qt-gen/test_outputs/signals.rs @@ -7,11 +7,11 @@ mod my_object { type MyObjectQt; include!("cxx-qt-lib/include/qt_types.h"); #[namespace = ""] - type QColor = cxx_qt_lib::QColorCpp; + type QColor = cxx_qt_lib::QColor; #[namespace = ""] type QDate = cxx_qt_lib::QDate; #[namespace = ""] - type QDateTime = cxx_qt_lib::QDateTimeCpp; + type QDateTime = cxx_qt_lib::QDateTime; #[namespace = ""] type QPoint = cxx_qt_lib::QPoint; #[namespace = ""] @@ -25,13 +25,13 @@ mod my_object { #[namespace = ""] type QSizeF = cxx_qt_lib::QSizeF; #[namespace = ""] - type QString = cxx_qt_lib::QStringCpp; + type QString = cxx_qt_lib::QString; #[namespace = ""] type QTime = cxx_qt_lib::QTime; #[namespace = ""] - type QUrl = cxx_qt_lib::QUrlCpp; + type QUrl = cxx_qt_lib::QUrl; #[namespace = ""] - type QVariant = cxx_qt_lib::QVariantCpp; + type QVariant = cxx_qt_lib::QVariant; #[rust_name = "ready"] fn ready(self: Pin<&mut MyObjectQt>); @@ -71,9 +71,8 @@ pub use self::cxx_qt_my_object::*; mod cxx_qt_my_object { use super::my_object::*; - use cxx_qt_lib::ToUniquePtr; - pub type FFICppObj = super::my_object::MyObjectQt; + type UniquePtr = cxx::UniquePtr; use cxx_qt_lib::QVariant; @@ -81,7 +80,7 @@ mod cxx_qt_my_object { Ready, DataChanged { first: i32, - second: QVariant, + second: UniquePtr, third: QPoint, }, } @@ -124,10 +123,7 @@ mod cxx_qt_my_object { first, second, third, - } => self - .cpp - .as_mut() - .emit_data_changed(first, second.to_unique_ptr(), third), + } => self.cpp.as_mut().emit_data_changed(first, second, third), } } @@ -138,10 +134,7 @@ mod cxx_qt_my_object { first, second, third, - } => self - .cpp - .as_mut() - .data_changed(first, &second.to_unique_ptr(), &third), + } => self.cpp.as_mut().data_changed(first, &second, &third), } } diff --git a/cxx-qt-gen/test_outputs/types_primitive_property.rs b/cxx-qt-gen/test_outputs/types_primitive_property.rs index 4c5c5f9a7..ddcfa515d 100644 --- a/cxx-qt-gen/test_outputs/types_primitive_property.rs +++ b/cxx-qt-gen/test_outputs/types_primitive_property.rs @@ -8,11 +8,11 @@ mod my_object { include!("cxx-qt-lib/include/qt_types.h"); #[namespace = ""] - type QColor = cxx_qt_lib::QColorCpp; + type QColor = cxx_qt_lib::QColor; #[namespace = ""] type QDate = cxx_qt_lib::QDate; #[namespace = ""] - type QDateTime = cxx_qt_lib::QDateTimeCpp; + type QDateTime = cxx_qt_lib::QDateTime; #[namespace = ""] type QPoint = cxx_qt_lib::QPoint; #[namespace = ""] @@ -26,13 +26,13 @@ mod my_object { #[namespace = ""] type QSizeF = cxx_qt_lib::QSizeF; #[namespace = ""] - type QString = cxx_qt_lib::QStringCpp; + type QString = cxx_qt_lib::QString; #[namespace = ""] type QTime = cxx_qt_lib::QTime; #[namespace = ""] - type QUrl = cxx_qt_lib::QUrlCpp; + type QUrl = cxx_qt_lib::QUrl; #[namespace = ""] - type QVariant = cxx_qt_lib::QVariantCpp; + type QVariant = cxx_qt_lib::QVariant; #[rust_name = "boolean"] fn getBoolean(self: &MyObjectQt) -> bool; @@ -99,9 +99,8 @@ pub use self::cxx_qt_my_object::*; mod cxx_qt_my_object { use super::my_object::*; - use cxx_qt_lib::ToUniquePtr; - pub type FFICppObj = super::my_object::MyObjectQt; + type UniquePtr = cxx::UniquePtr; #[derive(Default)] pub struct RustObj; diff --git a/cxx-qt-gen/test_outputs/types_qt_invokable.rs b/cxx-qt-gen/test_outputs/types_qt_invokable.rs index 59b86810e..569a4ef33 100644 --- a/cxx-qt-gen/test_outputs/types_qt_invokable.rs +++ b/cxx-qt-gen/test_outputs/types_qt_invokable.rs @@ -8,11 +8,11 @@ mod my_object { include!("cxx-qt-lib/include/qt_types.h"); #[namespace = ""] - type QColor = cxx_qt_lib::QColorCpp; + type QColor = cxx_qt_lib::QColor; #[namespace = ""] type QDate = cxx_qt_lib::QDate; #[namespace = ""] - type QDateTime = cxx_qt_lib::QDateTimeCpp; + type QDateTime = cxx_qt_lib::QDateTime; #[namespace = ""] type QPoint = cxx_qt_lib::QPoint; #[namespace = ""] @@ -26,13 +26,13 @@ mod my_object { #[namespace = ""] type QSizeF = cxx_qt_lib::QSizeF; #[namespace = ""] - type QString = cxx_qt_lib::QStringCpp; + type QString = cxx_qt_lib::QString; #[namespace = ""] type QTime = cxx_qt_lib::QTime; #[namespace = ""] - type QUrl = cxx_qt_lib::QUrlCpp; + type QUrl = cxx_qt_lib::QUrl; #[namespace = ""] - type QVariant = cxx_qt_lib::QVariantCpp; + type QVariant = cxx_qt_lib::QVariant; #[rust_name = "new_cpp_object"] fn newCppObject() -> UniquePtr; @@ -120,9 +120,8 @@ pub use self::cxx_qt_my_object::*; mod cxx_qt_my_object { use super::my_object::*; - use cxx_qt_lib::ToUniquePtr; - pub type FFICppObj = super::my_object::MyObjectQt; + type UniquePtr = cxx::UniquePtr; #[derive(Default)] pub struct RustObj; @@ -131,11 +130,10 @@ mod cxx_qt_my_object { pub fn test_color_wrapper( &self, _cpp: std::pin::Pin<&mut FFICppObj>, - color: &cxx_qt_lib::QColorCpp, - ) -> cxx::UniquePtr { + color: &cxx_qt_lib::QColor, + ) -> UniquePtr { let mut _cpp = CppObj::new(_cpp); - let color = color.to_rust(); - return self.test_color(&mut _cpp, &color).to_unique_ptr(); + return self.test_color(&mut _cpp, color); } pub fn test_date_wrapper( @@ -150,11 +148,10 @@ mod cxx_qt_my_object { pub fn test_date_time_wrapper( &self, _cpp: std::pin::Pin<&mut FFICppObj>, - dateTime: &cxx_qt_lib::QDateTimeCpp, - ) -> cxx::UniquePtr { + dateTime: &cxx_qt_lib::QDateTime, + ) -> UniquePtr { let mut _cpp = CppObj::new(_cpp); - let dateTime = dateTime.to_rust(); - return self.test_date_time(&mut _cpp, &dateTime).to_unique_ptr(); + return self.test_date_time(&mut _cpp, dateTime); } pub fn test_point_wrapper( @@ -214,11 +211,10 @@ mod cxx_qt_my_object { pub fn test_string_wrapper( &self, _cpp: std::pin::Pin<&mut FFICppObj>, - string: &cxx_qt_lib::QStringCpp, - ) -> cxx::UniquePtr { + string: &cxx_qt_lib::QString, + ) -> UniquePtr { let mut _cpp = CppObj::new(_cpp); - let string = string.to_rust(); - return self.test_string(&mut _cpp, &string).to_unique_ptr(); + return self.test_string(&mut _cpp, string); } pub fn test_time_wrapper( @@ -233,24 +229,22 @@ mod cxx_qt_my_object { pub fn test_url_wrapper( &self, _cpp: std::pin::Pin<&mut FFICppObj>, - url: &cxx_qt_lib::QUrlCpp, - ) -> cxx::UniquePtr { + url: &cxx_qt_lib::QUrl, + ) -> UniquePtr { let mut _cpp = CppObj::new(_cpp); - let url = url.to_rust(); - return self.test_url(&mut _cpp, &url).to_unique_ptr(); + return self.test_url(&mut _cpp, url); } pub fn test_variant_wrapper( &self, _cpp: std::pin::Pin<&mut FFICppObj>, - variant: &cxx_qt_lib::QVariantCpp, - ) -> cxx::UniquePtr { + variant: &cxx_qt_lib::QVariant, + ) -> UniquePtr { let mut _cpp = CppObj::new(_cpp); - let variant = variant.to_rust(); - return self.test_variant(&mut _cpp, &variant).to_unique_ptr(); + return self.test_variant(&mut _cpp, variant); } - pub fn test_color(&self, _cpp: &mut CppObj, color: &QColor) -> QColor { + pub fn test_color(&self, _cpp: &mut CppObj, color: &QColor) -> UniquePtr { color } @@ -258,7 +252,11 @@ mod cxx_qt_my_object { date } - pub fn test_date_time(&self, _cpp: &mut CppObj, dateTime: &QDateTime) -> QDateTime { + pub fn test_date_time( + &self, + _cpp: &mut CppObj, + dateTime: &QDateTime, + ) -> UniquePtr { dateTime } @@ -286,7 +284,7 @@ mod cxx_qt_my_object { sizef } - pub fn test_string(&self, _cpp: &mut CppObj, string: &str) -> String { + pub fn test_string(&self, _cpp: &mut CppObj, string: &QString) -> UniquePtr { string.to_owned() } @@ -294,11 +292,11 @@ mod cxx_qt_my_object { time } - pub fn test_url(&self, _cpp: &mut CppObj, url: &QUrl) -> QUrl { + pub fn test_url(&self, _cpp: &mut CppObj, url: &QUrl) -> UniquePtr { url } - pub fn test_variant(&self, _cpp: &mut CppObj, variant: &QVariant) -> QVariant { + pub fn test_variant(&self, _cpp: &mut CppObj, variant: &QVariant) -> UniquePtr { variant } } diff --git a/cxx-qt-gen/test_outputs/types_qt_property.rs b/cxx-qt-gen/test_outputs/types_qt_property.rs index 7097eec90..186874fc1 100644 --- a/cxx-qt-gen/test_outputs/types_qt_property.rs +++ b/cxx-qt-gen/test_outputs/types_qt_property.rs @@ -8,11 +8,11 @@ mod my_object { include!("cxx-qt-lib/include/qt_types.h"); #[namespace = ""] - type QColor = cxx_qt_lib::QColorCpp; + type QColor = cxx_qt_lib::QColor; #[namespace = ""] type QDate = cxx_qt_lib::QDate; #[namespace = ""] - type QDateTime = cxx_qt_lib::QDateTimeCpp; + type QDateTime = cxx_qt_lib::QDateTime; #[namespace = ""] type QPoint = cxx_qt_lib::QPoint; #[namespace = ""] @@ -26,13 +26,13 @@ mod my_object { #[namespace = ""] type QSizeF = cxx_qt_lib::QSizeF; #[namespace = ""] - type QString = cxx_qt_lib::QStringCpp; + type QString = cxx_qt_lib::QString; #[namespace = ""] type QTime = cxx_qt_lib::QTime; #[namespace = ""] - type QUrl = cxx_qt_lib::QUrlCpp; + type QUrl = cxx_qt_lib::QUrl; #[namespace = ""] - type QVariant = cxx_qt_lib::QVariantCpp; + type QVariant = cxx_qt_lib::QVariant; #[rust_name = "color"] fn getColor(self: &MyObjectQt) -> &QColor; @@ -119,9 +119,8 @@ pub use self::cxx_qt_my_object::*; mod cxx_qt_my_object { use super::my_object::*; - use cxx_qt_lib::ToUniquePtr; - pub type FFICppObj = super::my_object::MyObjectQt; + type UniquePtr = cxx::UniquePtr; #[derive(Default)] pub struct RustObj; @@ -137,12 +136,12 @@ mod cxx_qt_my_object { Self { cpp } } - pub fn color(&self) -> cxx_qt_lib::QColor { - self.cpp.color().to_rust() + pub fn color(&self) -> &cxx_qt_lib::QColor { + self.cpp.color() } - pub fn set_color(&mut self, value: cxx_qt_lib::QColor) { - self.cpp.as_mut().set_color(&value.to_unique_ptr()); + pub fn set_color(&mut self, value: &cxx_qt_lib::QColor) { + self.cpp.as_mut().set_color(value); } pub fn date(&self) -> &cxx_qt_lib::QDate { @@ -153,12 +152,12 @@ mod cxx_qt_my_object { self.cpp.as_mut().set_date(value); } - pub fn date_time(&self) -> cxx_qt_lib::QDateTime { - self.cpp.date_time().to_rust() + pub fn date_time(&self) -> &cxx_qt_lib::QDateTime { + self.cpp.date_time() } - pub fn set_date_time(&mut self, value: cxx_qt_lib::QDateTime) { - self.cpp.as_mut().set_date_time(&value.to_unique_ptr()); + pub fn set_date_time(&mut self, value: &cxx_qt_lib::QDateTime) { + self.cpp.as_mut().set_date_time(value); } pub fn point(&self) -> &cxx_qt_lib::QPoint { @@ -209,12 +208,12 @@ mod cxx_qt_my_object { self.cpp.as_mut().set_sizef(value); } - pub fn string(&self) -> String { - self.cpp.string().to_rust() + pub fn string(&self) -> &cxx_qt_lib::QString { + self.cpp.string() } - pub fn set_string(&mut self, value: &str) { - self.cpp.as_mut().set_string(&value.to_unique_ptr()); + pub fn set_string(&mut self, value: &cxx_qt_lib::QString) { + self.cpp.as_mut().set_string(value); } pub fn time(&self) -> &cxx_qt_lib::QTime { @@ -225,54 +224,54 @@ mod cxx_qt_my_object { self.cpp.as_mut().set_time(value); } - pub fn url(&self) -> cxx_qt_lib::QUrl { - self.cpp.url().to_rust() + pub fn url(&self) -> &cxx_qt_lib::QUrl { + self.cpp.url() } - pub fn set_url(&mut self, value: cxx_qt_lib::QUrl) { - self.cpp.as_mut().set_url(&value.to_unique_ptr()); + pub fn set_url(&mut self, value: &cxx_qt_lib::QUrl) { + self.cpp.as_mut().set_url(value); } - pub fn variant(&self) -> cxx_qt_lib::QVariant { - self.cpp.variant().to_rust() + pub fn variant(&self) -> &cxx_qt_lib::QVariant { + self.cpp.variant() } - pub fn set_variant(&mut self, value: cxx_qt_lib::QVariant) { - self.cpp.as_mut().set_variant(&value.to_unique_ptr()); + pub fn set_variant(&mut self, value: &cxx_qt_lib::QVariant) { + self.cpp.as_mut().set_variant(value); } pub fn grab_values_from_data(&mut self, mut data: Data) { - self.set_color(std::mem::take(&mut data.color)); + self.set_color(data.color.as_ref().unwrap()); self.set_date(&data.date); - self.set_date_time(std::mem::take(&mut data.date_time)); + self.set_date_time(data.date_time.as_ref().unwrap()); self.set_point(&data.point); self.set_pointf(&data.pointf); self.set_rect(&data.rect); self.set_rectf(&data.rectf); self.set_size(&data.size); self.set_sizef(&data.sizef); - self.set_string(&data.string); + self.set_string(data.string.as_ref().unwrap()); self.set_time(&data.time); - self.set_url(std::mem::take(&mut data.url)); - self.set_variant(std::mem::take(&mut data.variant)); + self.set_url(data.url.as_ref().unwrap()); + self.set_variant(data.variant.as_ref().unwrap()); } } #[derive(Default)] pub struct Data { - color: QColor, + color: UniquePtr, date: QDate, - date_time: QDateTime, + date_time: UniquePtr, point: QPoint, pointf: QPointF, rect: QRect, rectf: QRectF, size: QSize, sizef: QSizeF, - string: String, + string: UniquePtr, time: QTime, - url: QUrl, - variant: QVariant, + url: UniquePtr, + variant: UniquePtr, } impl<'a> From<&CppObj<'a>> for Data { diff --git a/cxx-qt-lib/include/qt_types.h b/cxx-qt-lib/include/qt_types.h index 30de262a3..4c8ca2d0f 100644 --- a/cxx-qt-lib/include/qt_types.h +++ b/cxx-qt-lib/include/qt_types.h @@ -166,12 +166,14 @@ qsizefInitDefault(); QSizeF qsizefInit(qreal width, qreal height); -std::unique_ptr -qstringInitFromRustString(rust::Str string); QString qstringFromRustString(rust::Str string); rust::String qstringToRustString(const QString& string); +std::unique_ptr +qstringInitFromRustString(rust::Str string); +std::unique_ptr +qstringInitFromQString(const QString& string); QTime qtimeInitDefault(); diff --git a/cxx-qt-lib/src/lib.rs b/cxx-qt-lib/src/lib.rs index d8f26a7a6..69bcf43f4 100644 --- a/cxx-qt-lib/src/lib.rs +++ b/cxx-qt-lib/src/lib.rs @@ -10,11 +10,3 @@ pub use types::*; pub trait UpdateRequestHandler { fn handle_update_request(&mut self, cpp: &mut C); } - -pub trait ToUniquePtr { - type CppType; - - fn to_unique_ptr(self) -> cxx::UniquePtr - where - Self::CppType: cxx::memory::UniquePtrTarget; -} diff --git a/cxx-qt-lib/src/qt_types.cpp b/cxx-qt-lib/src/qt_types.cpp index 7f67bddef..c2da52e6c 100644 --- a/cxx-qt-lib/src/qt_types.cpp +++ b/cxx-qt-lib/src/qt_types.cpp @@ -162,12 +162,12 @@ qsizefInit(qreal width, qreal height) return QSizeF(width, height); } -std::unique_ptr -qstringInitFromRustString(rust::Str string) +rust::String +qstringToRustString(const QString& string) { - // Note that rust::Str here is borrowed - // and we convert back from UTF-8 to UTF-16 - return std::make_unique(qstringFromRustString(string)); + // Note that this changes UTF-16 to UTF-8 + const auto byteArray = string.toUtf8(); + return rust::String(byteArray.constData(), byteArray.size()); } QString @@ -178,12 +178,18 @@ qstringFromRustString(rust::Str string) return QString::fromUtf8(string.data(), string.size()); } -rust::String -qstringToRustString(const QString& string) +std::unique_ptr +qstringInitFromRustString(rust::Str string) { - // Note that this changes UTF-16 to UTF-8 - const auto byteArray = string.toUtf8(); - return rust::String(byteArray.constData(), byteArray.size()); + // Note that rust::Str here is borrowed + // and we convert back from UTF-8 to UTF-16 + return std::make_unique(qstringFromRustString(string)); +} + +std::unique_ptr +qstringInitFromQString(const QString& string) +{ + return std::make_unique(string); } QTime diff --git a/cxx-qt-lib/src/types/mod.rs b/cxx-qt-lib/src/types/mod.rs index a0d27e613..d6843c5c2 100644 --- a/cxx-qt-lib/src/types/mod.rs +++ b/cxx-qt-lib/src/types/mod.rs @@ -4,13 +4,13 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 mod qcolor; -pub use qcolor::{QColor, QColorCpp}; +pub use qcolor::QColor; mod qdate; pub use qdate::QDate; mod qdatetime; -pub use qdatetime::{QDateTime, QDateTimeCpp}; +pub use qdatetime::QDateTime; mod qrect; pub use qrect::QRect; @@ -25,7 +25,7 @@ mod qsizef; pub use qsizef::QSizeF; mod qstring; -pub use qstring::QStringCpp; +pub use qstring::QString; mod qtime; pub use qtime::QTime; @@ -37,10 +37,10 @@ mod qpointf; pub use qpointf::QPointF; mod qurl; -pub use qurl::{QUrl, QUrlCpp}; +pub use qurl::QUrl; mod qvariant; -pub use qvariant::{QVariant, QVariantCpp, QVariantValue}; +pub use qvariant::{QVariant, QVariantValue}; mod update_requester; pub use update_requester::{UpdateRequester, UpdateRequesterCpp}; diff --git a/cxx-qt-lib/src/types/qcolor.rs b/cxx-qt-lib/src/types/qcolor.rs index 8517a0927..240ec048f 100644 --- a/cxx-qt-lib/src/types/qcolor.rs +++ b/cxx-qt-lib/src/types/qcolor.rs @@ -43,128 +43,29 @@ mod ffi { /// Note that we only expose RGB methods for now. /// /// Note that this is the C++ representation and QColor should be used in Rust. -pub type QColorCpp = ffi::QColor; - -impl QColorCpp { - /// Create a new Rust QColor from this QColorCpp. - /// This is a copy operation so any changes will not propagate to the original QColorCpp. - pub fn to_rust(&self) -> QColor { - QColor::from_qcolor(self) - } -} - -/// The Rust representation of Qt's QColor -/// -/// Internally this holds a UniquePtr to a QColorCpp which has been constructed on the C++ side. -pub struct QColor { - inner: cxx::UniquePtr, -} - -impl Default for QColor { - fn default() -> Self { - QColor::from_unique_ptr(ffi::qcolor_init()) - } -} +pub type QColor = ffi::QColor; impl QColor { - /// Construct a Rust QColor from an existing UniquePtr this is a move operation - /// - /// This is used in QVariant::value so that we don't need to perform another copy - pub(crate) fn from_unique_ptr(color: cxx::UniquePtr) -> Self { - Self { inner: color } + /// Construct a default null QColor + pub fn null() -> cxx::UniquePtr { + ffi::qcolor_init() } /// Construct a Rust QColor from an existing QColorCpp, this is a copy operation. - pub fn from_qcolor(color: &QColorCpp) -> Self { - Self { - inner: ffi::qcolor_init_from_qcolor(color), - } + pub fn from_ref(color: &QColor) -> cxx::UniquePtr { + ffi::qcolor_init_from_qcolor(color) } /// Constructs a QColor with the RGB value r, g, b, and the alpha-channel (transparency) value of a. /// /// The color is left invalid if any of the arguments are invalid. - pub fn from_rgba(red: i32, green: i32, blue: i32, alpha: i32) -> Self { - QColor::from_unique_ptr(ffi::qcolor_init_from_rgba(red, green, blue, alpha)) - } - - /// Returns the alpha color component of this color. - pub fn alpha(&self) -> i32 { - if let Some(inner) = self.inner.as_ref() { - inner.alpha() - } else { - 0 - } - } - - /// Returns the blue color component of this color. - pub fn blue(&self) -> i32 { - if let Some(inner) = self.inner.as_ref() { - inner.blue() - } else { - 0 - } - } - - /// Returns the green color component of this color. - pub fn green(&self) -> i32 { - if let Some(inner) = self.inner.as_ref() { - inner.green() - } else { - 0 - } - } - - /// Returns the red color component of this color. - pub fn red(&self) -> i32 { - if let Some(inner) = self.inner.as_ref() { - inner.red() - } else { - 0 - } - } - - /// Sets the alpha of this color to alpha. Integer alpha is specified in the range 0-255. - pub fn set_alpha(&mut self, alpha: i32) { - if let Some(inner) = self.inner.as_mut() { - inner.set_alpha(alpha); - } - } - - /// Sets the blue color component of this color to blue. Integer components are specified in the range 0-255. - pub fn set_blue(&mut self, blue: i32) { - if let Some(inner) = self.inner.as_mut() { - inner.set_blue(blue); - } - } - - /// Sets the green color component of this color to green. Integer components are specified in the range 0-255. - pub fn set_green(&mut self, green: i32) { - if let Some(inner) = self.inner.as_mut() { - inner.set_green(green); - } - } - - /// Sets the red color component of this color to red. Integer components are specified in the range 0-255. - pub fn set_red(&mut self, red: i32) { - if let Some(inner) = self.inner.as_mut() { - inner.set_red(red); - } - } -} - -impl crate::ToUniquePtr for QColor { - type CppType = QColorCpp; - - /// Retrieve the UniquePtr to the Qt QColorCpp of this Rust QColor - /// so that this object can be passed back to C++. - fn to_unique_ptr(self) -> cxx::UniquePtr { - self.inner + pub fn from_rgba(red: i32, green: i32, blue: i32, alpha: i32) -> cxx::UniquePtr { + ffi::qcolor_init_from_rgba(red, green, blue, alpha) } } -impl From<&QColorCpp> for QColor { - fn from(qcolor: &QColorCpp) -> Self { - qcolor.to_rust() +impl From<&QColor> for cxx::UniquePtr { + fn from(value: &QColor) -> cxx::UniquePtr { + QColor::from_ref(value) } } diff --git a/cxx-qt-lib/src/types/qdatetime.rs b/cxx-qt-lib/src/types/qdatetime.rs index ed3911785..9f4a1de9c 100644 --- a/cxx-qt-lib/src/types/qdatetime.rs +++ b/cxx-qt-lib/src/types/qdatetime.rs @@ -45,98 +45,39 @@ mod ffi { /// The QDateTimeCpp class provides date and time functions. /// /// Note that this is the C++ representation and QDateTime should be used in Rust. -pub type QDateTimeCpp = ffi::QDateTime; - -impl QDateTimeCpp { - /// Create a new Rust QDateTime from this QDateTimeCpp. - /// This is a copy operation so any changes will not propagate to the original QDateTimeCpp. - pub fn to_rust(&self) -> QDateTime { - QDateTime::from_qdatetime(self) - } -} - -/// The Rust representation of Qt's QDateTime -/// -/// Internally this holds a UniquePtr to a QDateTimeCpp which has been constructed on the C++ side. -pub struct QDateTime { - inner: cxx::UniquePtr, -} - -impl Default for QDateTime { - fn default() -> Self { - QDateTime::from_unique_ptr(ffi::qdatetime_init()) - } -} +pub type QDateTime = ffi::QDateTime; impl QDateTime { - /// Construct a Rust QDateTime from an existing UniquePtr this is a move operation - /// - /// This is used in QVariant::value so that we don't need to perform another copy - pub(crate) fn from_unique_ptr(ptr: cxx::UniquePtr) -> Self { - Self { inner: ptr } + /// Constrct a default null QDateTime + pub fn null() -> cxx::UniquePtr { + ffi::qdatetime_init() } /// Construct a Rust QDateTime from an existing QDateTimeCpp, this is a copy operation. - pub fn from_qdatetime(qdatetime: &QDateTimeCpp) -> Self { - Self { - inner: ffi::qdatetime_init_from_qdatetime(qdatetime), - } + pub fn from_ref(qdatetime: &QDateTime) -> cxx::UniquePtr { + ffi::qdatetime_init_from_qdatetime(qdatetime) } /// Construct a Rust QDateTime from a given QDate and QTime - pub fn from_date_and_time(date: &QDate, time: &QTime) -> Self { - Self { - inner: ffi::qdatetime_init_from_date_and_time(date, time), - } - } - - /// Returns the date part of the datetime. - pub fn date(&self) -> QDate { - if let Some(inner) = self.inner.as_ref() { - inner.date() - } else { - QDate::default() - } - } - - /// Returns the time part of the datetime. - pub fn time(&self) -> QTime { - if let Some(inner) = self.inner.as_ref() { - inner.time() - } else { - QTime::default() - } + pub fn from_date_and_time(date: &QDate, time: &QTime) -> cxx::UniquePtr { + ffi::qdatetime_init_from_date_and_time(date, time) } /// Sets the date part of this datetime to date. If no time is set yet, it is set to midnight. /// If date is invalid, this QDateTime becomes invalid. - pub fn set_date(&mut self, date: QDate) { - if let Some(inner) = self.inner.as_mut() { - ffi::qdatetime_set_date(inner, date); - } + pub fn set_date(self: std::pin::Pin<&mut Self>, date: QDate) { + ffi::qdatetime_set_date(self, date); } /// Sets the time part of this datetime to time. If time is not valid, this function sets it to midnight. /// Therefore, it's possible to clear any set time in a QDateTimeCpp by setting it to a default QTime: - pub fn set_time(&mut self, time: QTime) { - if let Some(inner) = self.inner.as_mut() { - ffi::qdatetime_set_time(inner, time); - } - } -} - -impl crate::ToUniquePtr for QDateTime { - type CppType = QDateTimeCpp; - - /// Retrieve the UniquePtr to the Qt QDateTimeCpp of this Rust QDateTime - /// so that this object can be passed back to C++. - fn to_unique_ptr(self) -> cxx::UniquePtr { - self.inner + pub fn set_time(self: std::pin::Pin<&mut Self>, time: QTime) { + ffi::qdatetime_set_time(self, time); } } -impl From<&QDateTimeCpp> for QDateTime { - fn from(qdatetime: &QDateTimeCpp) -> Self { - qdatetime.to_rust() +impl From<&QDateTime> for cxx::UniquePtr { + fn from(value: &QDateTime) -> cxx::UniquePtr { + QDateTime::from_ref(value) } } diff --git a/cxx-qt-lib/src/types/qstring.rs b/cxx-qt-lib/src/types/qstring.rs index 9103e2fa7..285ce5e63 100644 --- a/cxx-qt-lib/src/types/qstring.rs +++ b/cxx-qt-lib/src/types/qstring.rs @@ -11,54 +11,44 @@ mod ffi { type QString; + #[namespace = "rust::cxxqtlib1"] + #[rust_name = "qstring_to_rust_string"] + fn qstringToRustString(string: &QString) -> String; + #[namespace = "rust::cxxqtlib1"] #[rust_name = "qstring_init_from_rust_string"] fn qstringInitFromRustString(string: &str) -> UniquePtr; #[namespace = "rust::cxxqtlib1"] - #[rust_name = "qstring_to_rust_string"] - fn qstringToRustString(string: &QString) -> String; + #[rust_name = "qstring_init_from_qstring"] + fn qstringInitFromQString(string: &QString) -> UniquePtr; } impl UniquePtr {} } -/// The QStringCpp class provides a Unicode character string. +/// The QString class provides a Unicode character string. /// /// Note that this is the C++ representation and String or &str should be used in Rust. -pub type QStringCpp = ffi::QString; +pub type QString = ffi::QString; -impl QStringCpp { - /// Create a new Rust String from this QStringCpp. This operation - /// needs to convert the UTF-16 data in the QString to UTF-8 - /// data and thus likely needs to an allocate. This is essentially - /// a copy and so any changes will not propagate to the QStringCpp. - pub fn to_rust(&self) -> String { - ffi::qstring_to_rust_string(self) +impl QString { + pub fn from_ref(string: &QString) -> cxx::UniquePtr { + ffi::qstring_init_from_qstring(string) } -} -impl crate::ToUniquePtr for &String { - type CppType = QStringCpp; - - /// Retrieve the UniquePtr to the Qt QStringCpp of this Rust String - /// so that this object can be passed back to C++. - fn to_unique_ptr(self) -> cxx::UniquePtr { - ffi::qstring_init_from_rust_string(self.as_ref()) + pub fn from_str(str: &str) -> cxx::UniquePtr { + ffi::qstring_init_from_rust_string(str) } } -impl crate::ToUniquePtr for &str { - type CppType = QStringCpp; - - /// Retrieve the UniquePtr to the Qt QStringCpp of this Rust &str - /// so that this object can be passed back to C++. - fn to_unique_ptr(self) -> cxx::UniquePtr { - ffi::qstring_init_from_rust_string(self) +impl std::fmt::Display for QString { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", ffi::qstring_to_rust_string(self)) } } -impl From<&QStringCpp> for String { - fn from(qstring: &QStringCpp) -> Self { - qstring.to_rust() +impl From<&QString> for cxx::UniquePtr { + fn from(value: &QString) -> cxx::UniquePtr { + QString::from_ref(value) } } diff --git a/cxx-qt-lib/src/types/qurl.rs b/cxx-qt-lib/src/types/qurl.rs index a6098ed7c..e9c15b8d9 100644 --- a/cxx-qt-lib/src/types/qurl.rs +++ b/cxx-qt-lib/src/types/qurl.rs @@ -31,42 +31,21 @@ mod ffi { /// The QUrlCpp class provides a convenient interface for working with URLs. /// /// Note that this is the C++ representation and QUrl should be used in Rust. -pub type QUrlCpp = ffi::QUrl; - -impl QUrlCpp { - /// Create a new Rust QUrl from this QUrlCpp. - /// This is a copy operation so any changes will not propagate to the original QUrlCpp. - pub fn to_rust(&self) -> QUrl { - QUrl::from_qurl(self) - } -} - -/// The Rust representation of Qt's QUrl -/// -/// Internally this holds a UniquePtr to a QUrlCpp which has been constructed on the C++ side. -pub struct QUrl { - inner: cxx::UniquePtr, -} - -impl Default for QUrl { - fn default() -> Self { - QUrl::from_unique_ptr(ffi::qurl_init()) - } -} +pub type QUrl = ffi::QUrl; impl QUrl { - /// Construct a Rust QUrl from an existing UniquePtr this is a move operation - /// - /// This is used in QVariant::value so that we don't need to perform another copy - pub(crate) fn from_unique_ptr(ptr: cxx::UniquePtr) -> Self { - Self { inner: ptr } + /// Constrct a default null QUrl + pub fn null() -> cxx::UniquePtr { + ffi::qurl_init() } /// Construct a Rust QUrl from an existing QUrlCpp, this is a copy operation. - pub fn from_qurl(qurl: &QUrlCpp) -> Self { - Self { - inner: ffi::qurl_init_from_qurl(qurl), - } + pub fn from_ref(qurl: &QUrl) -> cxx::UniquePtr { + ffi::qurl_init_from_qurl(qurl) + } + + pub fn from_str(str: &str) -> cxx::UniquePtr { + ffi::qurl_init_from_string(str) } // TODO: other QUrl methods @@ -82,37 +61,12 @@ impl QUrl { /// Returns a string representation of the URL. pub fn string(&self) -> String { - if let Some(inner) = self.inner.as_ref() { - ffi::qurl_to_rust_string(inner) - } else { - "".to_owned() - } - } -} - -impl std::str::FromStr for QUrl { - type Err = std::convert::Infallible; - - /// Constructs a URL by parsing the given string. - fn from_str(string: &str) -> Result { - Ok(Self { - inner: ffi::qurl_init_from_string(string), - }) - } -} - -impl crate::ToUniquePtr for QUrl { - type CppType = QUrlCpp; - - /// Retrieve the UniquePtr to the Qt QUrlCpp of this Rust QUrl - /// so that this object can be passed back to C++. - fn to_unique_ptr(self) -> cxx::UniquePtr { - self.inner + ffi::qurl_to_rust_string(self) } } -impl From<&QUrlCpp> for QUrl { - fn from(qurl: &QUrlCpp) -> Self { - qurl.to_rust() +impl From<&QUrl> for cxx::UniquePtr { + fn from(value: &QUrl) -> cxx::UniquePtr { + QUrl::from_ref(value) } } diff --git a/cxx-qt-lib/src/types/qvariant.rs b/cxx-qt-lib/src/types/qvariant.rs index 1fbb15440..c1961913e 100644 --- a/cxx-qt-lib/src/types/qvariant.rs +++ b/cxx-qt-lib/src/types/qvariant.rs @@ -4,10 +4,7 @@ // // SPDX-License-Identifier: MIT OR Apache-2.0 -use crate::{ - QColor, QDate, QDateTime, QPoint, QPointF, QRect, QRectF, QSize, QSizeF, QTime, QUrl, - ToUniquePtr, -}; +use crate::{QColor, QDate, QDateTime, QPoint, QPointF, QRect, QRectF, QSize, QSizeF, QTime, QUrl}; #[cxx::bridge] mod ffi { @@ -41,9 +38,9 @@ mod ffi { unsafe extern "C++" { include!("cxx-qt-lib/include/qt_types.h"); - type QColor = crate::QColorCpp; + type QColor = crate::QColor; type QDate = crate::QDate; - type QDateTime = crate::QDateTimeCpp; + type QDateTime = crate::QDateTime; type QPoint = crate::QPoint; type QPointF = crate::QPointF; type QRect = crate::QRect; @@ -51,7 +48,7 @@ mod ffi { type QSize = crate::QSize; type QSizeF = crate::QSizeF; type QTime = crate::QTime; - type QUrl = crate::QUrlCpp; + type QUrl = crate::QUrl; type QVariant; #[namespace = "rust::cxxqtlib1::types"] @@ -162,15 +159,7 @@ mod ffi { /// The QVariantCpp class acts like a union for the most common Qt data types. /// /// Note that this is the C++ representation and QVariant should be used in Rust. -pub type QVariantCpp = ffi::QVariant; - -impl QVariantCpp { - /// Create a new Rust QVariant from this QVariantCpp. - /// This is a copy operation so any changes will not propagate to the original QVariantCpp. - pub fn to_rust(&self) -> QVariant { - QVariant::from(self) - } -} +pub type QVariant = ffi::QVariant; /// The Rust inner value of a QVariant pub enum QVariantValue { @@ -181,9 +170,9 @@ pub enum QVariantValue { I8(i8), I16(i16), I32(i32), - QColor(QColor), + QColor(cxx::UniquePtr), QDate(QDate), - QDateTime(QDateTime), + QDateTime(cxx::UniquePtr), QPoint(QPoint), QPointF(QPointF), QRect(QRect), @@ -191,7 +180,8 @@ pub enum QVariantValue { QSize(QSize), QSizeF(QSizeF), QTime(QTime), - QUrl(QUrl), + QUrl(cxx::UniquePtr), + // TODO: should we go to QString so the developer has to invoke the UTF translation? String(String), U8(u8), U16(u16), @@ -199,50 +189,50 @@ pub enum QVariantValue { } // Define how we convert from other types into a QVariantCpp -trait IntoQVariantCpp { - fn into_qvariant(self) -> cxx::UniquePtr; +pub trait IntoQVariant { + fn into_qvariant(self) -> cxx::UniquePtr; } macro_rules! into_qvariant { ($typeName:ty, $name:expr) => { - impl IntoQVariantCpp for $typeName { - fn into_qvariant(self) -> cxx::UniquePtr { + impl IntoQVariant for $typeName { + fn into_qvariant(self) -> cxx::UniquePtr { $name(self) } } }; } +// TODO: should we take by ref or value for trivial types? macro_rules! into_qvariant_ref { ($typeName:ty, $name:expr) => { - impl IntoQVariantCpp for $typeName { - fn into_qvariant(self) -> cxx::UniquePtr { + impl IntoQVariant for $typeName { + fn into_qvariant(self) -> cxx::UniquePtr { $name(&self) } } }; } -macro_rules! into_qvariant_opaque { +macro_rules! into_qvariant_opaque_ref { ($typeName:ty, $name:expr) => { - impl IntoQVariantCpp for $typeName { - fn into_qvariant(self) -> cxx::UniquePtr { - $name(&self.to_unique_ptr()) + impl IntoQVariant for &$typeName { + fn into_qvariant(self) -> cxx::UniquePtr { + $name(self) } } }; } -into_qvariant!(&QVariantCpp, ffi::qvariant_init_from_qvariant); into_qvariant!(bool, ffi::qvariant_init_from_bool); into_qvariant!(f32, ffi::qvariant_init_from_f32); into_qvariant!(f64, ffi::qvariant_init_from_f64); into_qvariant!(i8, ffi::qvariant_init_from_i8); into_qvariant!(i16, ffi::qvariant_init_from_i16); into_qvariant!(i32, ffi::qvariant_init_from_i32); -into_qvariant_opaque!(QColor, ffi::qvariant_init_from_qcolor); +into_qvariant_opaque_ref!(QColor, ffi::qvariant_init_from_qcolor); into_qvariant_ref!(QDate, ffi::qvariant_init_from_qdate); -into_qvariant_opaque!(QDateTime, ffi::qvariant_init_from_qdatetime); +into_qvariant_opaque_ref!(QDateTime, ffi::qvariant_init_from_qdatetime); into_qvariant_ref!(QPoint, ffi::qvariant_init_from_qpoint); into_qvariant_ref!(QPointF, ffi::qvariant_init_from_qpointf); into_qvariant_ref!(QRect, ffi::qvariant_init_from_qrect); @@ -250,98 +240,66 @@ into_qvariant_ref!(QRectF, ffi::qvariant_init_from_qrectf); into_qvariant_ref!(QSize, ffi::qvariant_init_from_qsize); into_qvariant_ref!(QSizeF, ffi::qvariant_init_from_qsizef); into_qvariant_ref!(QTime, ffi::qvariant_init_from_qtime); -into_qvariant_opaque!(QUrl, ffi::qvariant_init_from_qurl); +into_qvariant_opaque_ref!(QUrl, ffi::qvariant_init_from_qurl); into_qvariant_ref!(String, ffi::qvariant_init_from_rust_string); +// into_qvariant_opaque_ref!(QString, ffi::qvariant_init_from_rust_string); into_qvariant!(u8, ffi::qvariant_init_from_u8); into_qvariant!(u16, ffi::qvariant_init_from_u16); into_qvariant!(u32, ffi::qvariant_init_from_u32); -/// The Rust representation of Qt's QVariant -/// -/// Internally this holds a UniquePtr to a QVariantCpp which has been constructed on the C++ side. -pub struct QVariant { - inner: cxx::UniquePtr, -} - -impl Default for QVariant { - fn default() -> Self { - QVariant::from_unique_ptr(ffi::qvariant_init()) +impl QVariant { + pub fn from(value: T) -> cxx::UniquePtr + where + T: IntoQVariant, + { + value.into_qvariant() } -} -impl From for QVariant -where - T: IntoQVariantCpp, -{ - fn from(t: T) -> Self { - Self { - inner: t.into_qvariant(), - } + pub fn from_ref(value: &QVariant) -> cxx::UniquePtr { + ffi::qvariant_init_from_qvariant(value) } -} -impl QVariant { - /// Construct a Rust QVariant from an existing UniquePtr this is a move operation - /// - /// This is used in QVariant::default so that we don't need to perform another copy - fn from_unique_ptr(ptr: cxx::UniquePtr) -> Self { - Self { inner: ptr } + /// Constrct a default null QVariant + pub fn null() -> cxx::UniquePtr { + ffi::qvariant_init() } // TODO: add a set_value(&mut self, value: QVariantValue); /// Returns the value of the QVariant as a Rust enum pub fn value(&self) -> QVariantValue { - match ffi::qvariant_get_type(&self.inner) { + match ffi::qvariant_get_type(self) { ffi::QVariantType::Unsupported => QVariantValue::Unsupported, - ffi::QVariantType::Bool => QVariantValue::Bool(ffi::qvariant_to_bool(&self.inner)), - ffi::QVariantType::F32 => QVariantValue::F32(ffi::qvariant_to_f32(&self.inner)), - ffi::QVariantType::F64 => QVariantValue::F64(ffi::qvariant_to_f64(&self.inner)), - ffi::QVariantType::I8 => QVariantValue::I8(ffi::qvariant_to_i8(&self.inner)), - ffi::QVariantType::I16 => QVariantValue::I16(ffi::qvariant_to_i16(&self.inner)), - ffi::QVariantType::I32 => QVariantValue::I32(ffi::qvariant_to_i32(&self.inner)), - ffi::QVariantType::QColor => QVariantValue::QColor(QColor::from_unique_ptr( - ffi::qvariant_to_qcolor(&self.inner), - )), - ffi::QVariantType::QDate => QVariantValue::QDate(ffi::qvariant_to_qdate(&self.inner)), - ffi::QVariantType::QDateTime => QVariantValue::QDateTime(QDateTime::from_unique_ptr( - ffi::qvariant_to_qdatetime(&self.inner), - )), - ffi::QVariantType::QPoint => { - QVariantValue::QPoint(ffi::qvariant_to_qpoint(&self.inner)) - } - ffi::QVariantType::QPointF => { - QVariantValue::QPointF(ffi::qvariant_to_qpointf(&self.inner)) - } - ffi::QVariantType::QRect => QVariantValue::QRect(ffi::qvariant_to_qrect(&self.inner)), - ffi::QVariantType::QRectF => { - QVariantValue::QRectF(ffi::qvariant_to_qrectf(&self.inner)) + ffi::QVariantType::Bool => QVariantValue::Bool(ffi::qvariant_to_bool(self)), + ffi::QVariantType::F32 => QVariantValue::F32(ffi::qvariant_to_f32(self)), + ffi::QVariantType::F64 => QVariantValue::F64(ffi::qvariant_to_f64(self)), + ffi::QVariantType::I8 => QVariantValue::I8(ffi::qvariant_to_i8(self)), + ffi::QVariantType::I16 => QVariantValue::I16(ffi::qvariant_to_i16(self)), + ffi::QVariantType::I32 => QVariantValue::I32(ffi::qvariant_to_i32(self)), + ffi::QVariantType::QColor => QVariantValue::QColor(ffi::qvariant_to_qcolor(self)), + ffi::QVariantType::QDate => QVariantValue::QDate(ffi::qvariant_to_qdate(self)), + ffi::QVariantType::QDateTime => { + QVariantValue::QDateTime(ffi::qvariant_to_qdatetime(self)) } - ffi::QVariantType::QSize => QVariantValue::QSize(ffi::qvariant_to_qsize(&self.inner)), - ffi::QVariantType::QSizeF => { - QVariantValue::QSizeF(ffi::qvariant_to_qsizef(&self.inner)) - } - ffi::QVariantType::QTime => QVariantValue::QTime(ffi::qvariant_to_qtime(&self.inner)), - ffi::QVariantType::QUrl => { - QVariantValue::QUrl(QUrl::from_unique_ptr(ffi::qvariant_to_qurl(&self.inner))) - } - ffi::QVariantType::String => { - QVariantValue::String(ffi::qvariant_to_rust_string(&self.inner)) - } - ffi::QVariantType::U8 => QVariantValue::U8(ffi::qvariant_to_u8(&self.inner)), - ffi::QVariantType::U16 => QVariantValue::U16(ffi::qvariant_to_u16(&self.inner)), - ffi::QVariantType::U32 => QVariantValue::U32(ffi::qvariant_to_u32(&self.inner)), + ffi::QVariantType::QPoint => QVariantValue::QPoint(ffi::qvariant_to_qpoint(self)), + ffi::QVariantType::QPointF => QVariantValue::QPointF(ffi::qvariant_to_qpointf(self)), + ffi::QVariantType::QRect => QVariantValue::QRect(ffi::qvariant_to_qrect(self)), + ffi::QVariantType::QRectF => QVariantValue::QRectF(ffi::qvariant_to_qrectf(self)), + ffi::QVariantType::QSize => QVariantValue::QSize(ffi::qvariant_to_qsize(self)), + ffi::QVariantType::QSizeF => QVariantValue::QSizeF(ffi::qvariant_to_qsizef(self)), + ffi::QVariantType::QTime => QVariantValue::QTime(ffi::qvariant_to_qtime(self)), + ffi::QVariantType::QUrl => QVariantValue::QUrl(ffi::qvariant_to_qurl(self)), + ffi::QVariantType::String => QVariantValue::String(ffi::qvariant_to_rust_string(self)), + ffi::QVariantType::U8 => QVariantValue::U8(ffi::qvariant_to_u8(self)), + ffi::QVariantType::U16 => QVariantValue::U16(ffi::qvariant_to_u16(self)), + ffi::QVariantType::U32 => QVariantValue::U32(ffi::qvariant_to_u32(self)), _others => QVariantValue::Unsupported, } } } -impl crate::ToUniquePtr for QVariant { - type CppType = QVariantCpp; - - /// Retrieve the UniquePtr to the Qt QVariantCpp of this Rust QVariant - /// so that this object can be passed back to C++. - fn to_unique_ptr(self) -> cxx::UniquePtr { - self.inner +impl From<&QVariant> for cxx::UniquePtr { + fn from(value: &QVariant) -> cxx::UniquePtr { + QVariant::from_ref(value) } } diff --git a/examples/qml_extension_plugin/core/src/lib.rs b/examples/qml_extension_plugin/core/src/lib.rs index 982755e60..67228238e 100644 --- a/examples/qml_extension_plugin/core/src/lib.rs +++ b/examples/qml_extension_plugin/core/src/lib.rs @@ -6,21 +6,48 @@ // Note: keep any changes here in sync with the main README.md +use serde::{Deserialize, Serialize}; + +// Represent the Data struct below with serde friendly types, so we can (de)serialize it +#[derive(Deserialize, Serialize)] +pub struct DataSerde { + number: i32, + string: String, +} + +impl From for DataSerde { + fn from(value: Data) -> DataSerde { + DataSerde { + number: value.number, + string: value.string.to_string(), + } + } +} + #[cxx_qt::bridge] mod my_object { - use serde::{Deserialize, Serialize}; + use super::DataSerde; const DEFAULT_STR: &str = r#"{"number": 1, "string": "Hello World!"}"#; - #[derive(Deserialize, Serialize)] pub struct Data { - number: i32, - string: String, + pub number: i32, + pub string: UniquePtr, } impl Default for Data { fn default() -> Self { - serde_json::from_str(DEFAULT_STR).unwrap() + let data_serde: DataSerde = serde_json::from_str(DEFAULT_STR).unwrap(); + data_serde.into() + } + } + + impl From for Data { + fn from(value: DataSerde) -> Data { + Data { + number: value.number, + string: QString::from_str(&value.string), + } } } @@ -35,21 +62,23 @@ mod my_object { #[invokable] pub fn reset(&self, cpp: &mut CppObj) { - let data: Data = serde_json::from_str(DEFAULT_STR).unwrap(); - cpp.grab_values_from_data(data); + let data: DataSerde = serde_json::from_str(DEFAULT_STR).unwrap(); + cpp.grab_values_from_data(data.into()); } #[invokable] - pub fn serialize(&self, cpp: &mut CppObj) -> String { + pub fn serialize(&self, cpp: &mut CppObj) -> UniquePtr { let data = Data::from(cpp); - serde_json::to_string(&data).unwrap() + let data_serde = DataSerde::from(data); + let data_string = serde_json::to_string(&data_serde).unwrap(); + QString::from_str(&data_string) } #[invokable] pub fn grab_values(&self, cpp: &mut CppObj) { let string = r#"{"number": 2, "string": "Goodbye!"}"#; - let data: Data = serde_json::from_str(string).unwrap(); - cpp.grab_values_from_data(data); + let data: DataSerde = serde_json::from_str(string).unwrap(); + cpp.grab_values_from_data(data.into()); } } } diff --git a/examples/qml_features/src/lib.rs b/examples/qml_features/src/lib.rs index d44a10487..36d1ccd06 100644 --- a/examples/qml_features/src/lib.rs +++ b/examples/qml_features/src/lib.rs @@ -16,13 +16,21 @@ mod types; #[cxx_qt::bridge] mod my_object { - #[derive(Default)] pub struct Data { number: i32, - string: String, + string: UniquePtr, sub: crate::sub::cxx_qt_sub_object::CppObj, } + impl Default for Data { + fn default() -> Self { + Self { + number: 0, + string: QString::from_str(""), + } + } + } + #[derive(Default)] pub struct RustObj; @@ -45,7 +53,7 @@ mod my_object { } #[invokable] - pub fn say_hi(&self, string: &str, number: i32) { + pub fn say_hi(&self, string: &QString, number: i32) { println!( "Hi from Rust! String is {} and number is {}", string, number diff --git a/examples/qml_features/src/mock_qt_types.rs b/examples/qml_features/src/mock_qt_types.rs index d16ae73e8..115653bb3 100644 --- a/examples/qml_features/src/mock_qt_types.rs +++ b/examples/qml_features/src/mock_qt_types.rs @@ -10,18 +10,17 @@ mod mock_qt_types { QColor, QDate, QDateTime, QPoint, QPointF, QRect, QRectF, QSize, QSizeF, QTime, QUrl, QVariant, QVariantValue, }; - use std::str::FromStr; #[cxx_qt::signals(MyObject)] pub enum Signal { Ready, - DataChanged { variant: QVariant }, + DataChanged { variant: UniquePtr }, } pub struct Data { - color: QColor, + color: UniquePtr, date: QDate, - date_time: QDateTime, + date_time: UniquePtr, point: QPoint, pointf: QPointF, rect: QRect, @@ -29,8 +28,8 @@ mod mock_qt_types { size: QSize, sizef: QSizeF, time: QTime, - url: QUrl, - variant: QVariant, + url: UniquePtr, + variant: UniquePtr, } impl Default for Data { @@ -49,7 +48,7 @@ mod mock_qt_types { size: QSize::new(1, 3), sizef: QSizeF::new(1.0, 3.0), time: QTime::new(1, 2, 3, 4), - url: QUrl::from_str("https://github.com/KDAB").unwrap(), + url: QUrl::from_str("https://github.com/KDAB"), variant: QVariant::from(1_i32), } } @@ -79,11 +78,11 @@ mod mock_qt_types { #[invokable] pub fn test_color_property(&self, cpp: &mut CppObj) { - cpp.set_color(QColor::from_rgba(0, 0, 255, 255)); + cpp.set_color(QColor::from_rgba(0, 0, 255, 255).as_ref().unwrap()); } #[invokable] - pub fn test_color_invokable(&self, _color: &QColor) -> QColor { + pub fn test_color_invokable(&self, _color: &QColor) -> UniquePtr { QColor::from_rgba(0, 255, 0, 255) } @@ -113,11 +112,11 @@ mod mock_qt_types { date_time.time().msec() * 5, ), ); - cpp.set_date_time(new_date_time); + cpp.set_date_time(new_date_time.as_ref().unwrap()); } #[invokable] - pub fn test_date_time_invokable(&self, date_time: &QDateTime) -> QDateTime { + pub fn test_date_time_invokable(&self, date_time: &QDateTime) -> UniquePtr { QDateTime::from_date_and_time( &QDate::new(2021, 12, 31), &QTime::new( @@ -267,81 +266,105 @@ mod mock_qt_types { #[invokable] pub fn test_url_property(&self, cpp: &mut CppObj) { - let url = QUrl::from_str(&(cpp.url().string() + "/cxx-qt")).unwrap(); - cpp.set_url(url); + let url = QUrl::from_str(&(cpp.url().string() + "/cxx-qt")); + cpp.set_url(url.as_ref().unwrap()); } #[invokable] - pub fn test_url_invokable(&self, url: &QUrl) -> QUrl { - QUrl::from_str(&(url.string() + "/cxx-qt")).unwrap() + pub fn test_url_invokable(&self, url: &QUrl) -> UniquePtr { + QUrl::from_str(&(url.string() + "/cxx-qt")) } #[invokable] pub fn test_variant_property(&self, cpp: &mut CppObj) { match cpp.variant().value() { - QVariantValue::Bool(b) => cpp.set_variant(QVariant::from(!b)), - QVariantValue::F32(f) => cpp.set_variant(QVariant::from(f * 2.0)), - QVariantValue::F64(d) => cpp.set_variant(QVariant::from(d * 2.0)), - QVariantValue::I8(i) => cpp.set_variant(QVariant::from(i * 2)), - QVariantValue::I16(i) => cpp.set_variant(QVariant::from(i * 2)), - QVariantValue::I32(i) => cpp.set_variant(QVariant::from(i * 2)), + QVariantValue::Bool(b) => cpp.set_variant(QVariant::from(!b).as_ref().unwrap()), + QVariantValue::F32(f) => cpp.set_variant(QVariant::from(f * 2.0).as_ref().unwrap()), + QVariantValue::F64(d) => cpp.set_variant(QVariant::from(d * 2.0).as_ref().unwrap()), + QVariantValue::I8(i) => cpp.set_variant(QVariant::from(i * 2).as_ref().unwrap()), + QVariantValue::I16(i) => cpp.set_variant(QVariant::from(i * 2).as_ref().unwrap()), + QVariantValue::I32(i) => cpp.set_variant(QVariant::from(i * 2).as_ref().unwrap()), QVariantValue::QColor(mut color) => { - color.set_red(0); - color.set_green(0); - color.set_blue(255); - color.set_alpha(255); - cpp.set_variant(QVariant::from(color)); + if let Some(mut color) = color.as_mut() { + color.as_mut().set_red(0); + color.as_mut().set_green(0); + color.as_mut().set_blue(255); + color.as_mut().set_alpha(255); + } + cpp.set_variant(QVariant::from(color.as_ref().unwrap()).as_ref().unwrap()); } QVariantValue::QDate(mut date) => { date.set_date(2021, 12, 31); - cpp.set_variant(QVariant::from(date)); + cpp.set_variant(QVariant::from(date).as_ref().unwrap()); } QVariantValue::QDateTime(mut date_time) => { - date_time.set_date(QDate::new(2021, 12, 31)); - date_time.set_time(QTime::new( - date_time.time().hour() * 2, - date_time.time().minute() * 3, - date_time.time().second() * 4, - date_time.time().msec() * 5, - )); - cpp.set_variant(QVariant::from(date_time)); + if let Some(mut date_time) = date_time.as_mut() { + date_time.as_mut().set_date(QDate::new(2021, 12, 31)); + let new_time = QTime::new( + date_time.time().hour() * 2, + date_time.time().minute() * 3, + date_time.time().second() * 4, + date_time.time().msec() * 5, + ); + date_time.as_mut().set_time(new_time); + } + cpp.set_variant( + QVariant::from(date_time.as_ref().unwrap()) + .as_ref() + .unwrap(), + ); } QVariantValue::QPoint(point) => { - cpp.set_variant(QVariant::from(QPoint::new(point.x() * 2, point.y() * 2))); + cpp.set_variant( + QVariant::from(QPoint::new(point.x() * 2, point.y() * 2)) + .as_ref() + .unwrap(), + ); } QVariantValue::QPointF(pointf) => { - cpp.set_variant(QVariant::from(QPointF::new( - pointf.x() * 2.0, - pointf.y() * 2.0, - ))); + cpp.set_variant( + QVariant::from(QPointF::new(pointf.x() * 2.0, pointf.y() * 2.0)) + .as_ref() + .unwrap(), + ); } QVariantValue::QRect(rect) => { - cpp.set_variant(QVariant::from(QRect::new( - rect.x() * 2, - rect.y() * 3, - rect.width() * 4, - rect.height() * 5, - ))); + cpp.set_variant( + QVariant::from(QRect::new( + rect.x() * 2, + rect.y() * 3, + rect.width() * 4, + rect.height() * 5, + )) + .as_ref() + .unwrap(), + ); } QVariantValue::QRectF(rectf) => { - cpp.set_variant(QVariant::from(QRectF::new( - rectf.x() * 2.0, - rectf.y() * 3.0, - rectf.width() * 4.0, - rectf.height() * 5.0, - ))); + cpp.set_variant( + QVariant::from(QRectF::new( + rectf.x() * 2.0, + rectf.y() * 3.0, + rectf.width() * 4.0, + rectf.height() * 5.0, + )) + .as_ref() + .unwrap(), + ); } QVariantValue::QSize(size) => { - cpp.set_variant(QVariant::from(QSize::new( - size.width() * 2, - size.height() * 2, - ))); + cpp.set_variant( + QVariant::from(QSize::new(size.width() * 2, size.height() * 2)) + .as_ref() + .unwrap(), + ); } QVariantValue::QSizeF(sizef) => { - cpp.set_variant(QVariant::from(QSizeF::new( - sizef.width() * 2.0, - sizef.height() * 2.0, - ))); + cpp.set_variant( + QVariant::from(QSizeF::new(sizef.width() * 2.0, sizef.height() * 2.0)) + .as_ref() + .unwrap(), + ); } QVariantValue::QTime(mut time) => { time.set_hms( @@ -350,21 +373,21 @@ mod mock_qt_types { time.second() * 4, time.msec() * 5, ); - cpp.set_variant(QVariant::from(time)); + cpp.set_variant(QVariant::from(time).as_ref().unwrap()); } QVariantValue::QUrl(url) => { - let url = QUrl::from_str(&(url.string() + "/cxx-qt")).unwrap(); - cpp.set_variant(QVariant::from(url)); + let url = QUrl::from_str(&(url.string() + "/cxx-qt")); + cpp.set_variant(QVariant::from(url.as_ref().unwrap()).as_ref().unwrap()); } - QVariantValue::U8(i) => cpp.set_variant(QVariant::from(i * 2)), - QVariantValue::U16(i) => cpp.set_variant(QVariant::from(i * 2)), - QVariantValue::U32(i) => cpp.set_variant(QVariant::from(i * 2)), + QVariantValue::U8(i) => cpp.set_variant(QVariant::from(i * 2).as_ref().unwrap()), + QVariantValue::U16(i) => cpp.set_variant(QVariant::from(i * 2).as_ref().unwrap()), + QVariantValue::U32(i) => cpp.set_variant(QVariant::from(i * 2).as_ref().unwrap()), _ => panic!("Incorrect variant type!"), } } #[invokable] - pub fn test_variant_invokable(&self, variant: &QVariant) -> QVariant { + pub fn test_variant_invokable(&self, variant: &QVariant) -> UniquePtr { match variant.value() { QVariantValue::Bool(b) => QVariant::from(!b), QVariantValue::F32(f) => QVariant::from(f * 2.0), @@ -373,25 +396,30 @@ mod mock_qt_types { QVariantValue::I16(i) => QVariant::from(i * 2), QVariantValue::I32(i) => QVariant::from(i * 2), QVariantValue::QColor(mut color) => { - color.set_red(0); - color.set_green(255); - color.set_blue(0); - color.set_alpha(255); - QVariant::from(color) + if let Some(mut color) = color.as_mut() { + color.as_mut().set_red(0); + color.as_mut().set_green(255); + color.as_mut().set_blue(0); + color.as_mut().set_alpha(255); + } + QVariant::from(color.as_ref().unwrap()) } QVariantValue::QDate(mut date) => { date.set_date(2021, 12, 31); QVariant::from(date) } QVariantValue::QDateTime(mut date_time) => { - date_time.set_date(QDate::new(2021, 12, 31)); - date_time.set_time(QTime::new( - date_time.time().hour() * 2, - date_time.time().minute() * 3, - date_time.time().second() * 4, - date_time.time().msec() * 5, - )); - QVariant::from(date_time) + if let Some(mut date_time) = date_time.as_mut() { + date_time.as_mut().set_date(QDate::new(2021, 12, 31)); + let new_time = QTime::new( + date_time.time().hour() * 2, + date_time.time().minute() * 3, + date_time.time().second() * 4, + date_time.time().msec() * 5, + ); + date_time.as_mut().set_time(new_time); + } + QVariant::from(date_time.as_ref().unwrap()) } QVariantValue::QPoint(point) => { QVariant::from(QPoint::new(point.x() * 2, point.y() * 2)) @@ -427,8 +455,8 @@ mod mock_qt_types { QVariant::from(time) } QVariantValue::QUrl(url) => { - let url = QUrl::from_str(&(url.string() + "/cxx-qt")).unwrap(); - QVariant::from(url) + let url = QUrl::from_str(&(url.string() + "/cxx-qt")); + QVariant::from(url.as_ref().unwrap()) } QVariantValue::U8(i) => QVariant::from(i * 2), QVariantValue::U16(i) => QVariant::from(i * 2), diff --git a/examples/qml_features/src/serialisation.rs b/examples/qml_features/src/serialisation.rs index ed0c309f7..b75fe4958 100644 --- a/examples/qml_features/src/serialisation.rs +++ b/examples/qml_features/src/serialisation.rs @@ -5,20 +5,47 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 // ANCHOR: book_macro_code + +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, Serialize)] +pub struct DataSerde { + number: i32, + string: String, +} + +impl From for DataSerde { + fn from(value: Data) -> DataSerde { + DataSerde { + number: value.number, + string: value.string.to_string(), + } + } +} + #[cxx_qt::bridge] mod serialisation { - use serde::{Deserialize, Serialize}; + use super::DataSerde; - #[derive(Deserialize, Serialize)] pub struct Data { - number: i32, - string: String, + pub number: i32, + pub string: UniquePtr, } impl Default for Data { fn default() -> Self { let string = r#"{"number": 4, "string": "Hello World!"}"#; - serde_json::from_str(string).unwrap() + let data_serde: DataSerde = serde_json::from_str(string).unwrap(); + data_serde.into() + } + } + + impl From for Data { + fn from(value: DataSerde) -> Data { + Data { + number: value.number, + string: QString::from_str(&value.string), + } } } @@ -27,17 +54,19 @@ mod serialisation { impl RustObj { #[invokable] - pub fn as_json_str(&self, cpp: &mut CppObj) -> String { + pub fn as_json_str(&self, cpp: &mut CppObj) -> UniquePtr { let data = Data::from(cpp); - serde_json::to_string(&data).unwrap() + let data_serde = DataSerde::from(data); + let data_string = serde_json::to_string(&data_serde).unwrap(); + QString::from_str(&data_string) } // ANCHOR: book_grab_values #[invokable] pub fn grab_values(&self, cpp: &mut CppObj) { let string = r#"{"number": 2, "string": "Goodbye!"}"#; - let data: Data = serde_json::from_str(string).unwrap(); - cpp.grab_values_from_data(data); + let data_serde: DataSerde = serde_json::from_str(string).unwrap(); + cpp.grab_values_from_data(data_serde.into()); } // ANCHOR_END: book_grab_values } diff --git a/examples/qml_features/src/signals.rs b/examples/qml_features/src/signals.rs index dbaaec224..bc7f3c44e 100644 --- a/examples/qml_features/src/signals.rs +++ b/examples/qml_features/src/signals.rs @@ -14,15 +14,24 @@ pub mod signals { Ready, RustDataChanged { data: i32 }, TrivialDataChanged { trivial: QPoint }, - OpaqueDataChanged { opaque: QVariant }, + OpaqueDataChanged { opaque: UniquePtr }, } // ANCHOR_END: book_signals_enum - #[derive(Default)] pub struct Data { data: i32, trivial: QPoint, - opaque: QVariant, + opaque: UniquePtr, + } + + impl Default for Data { + fn default() -> Self { + Self { + data: 0, + trivial: QPoint::default(), + opaque: QVariant::null(), + } + } } #[derive(Default)] @@ -41,7 +50,7 @@ pub mod signals { trivial: *cpp.trivial(), }); cpp.emit_queued(Signal::OpaqueDataChanged { - opaque: cpp.opaque(), + opaque: QVariant::from_ref(cpp.opaque()), }); } } diff --git a/examples/qml_features/src/sub.rs b/examples/qml_features/src/sub.rs index 1d5bf6630..18fbc1af2 100644 --- a/examples/qml_features/src/sub.rs +++ b/examples/qml_features/src/sub.rs @@ -6,10 +6,18 @@ #[cxx_qt::bridge] pub mod sub_object { - #[derive(Default)] pub struct Data { number: i32, - string: String, + string: UniquePtr, + } + + impl Default for Data { + fn default() -> Self { + Self { + number: 0, + string: QString::from_str(""), + } + } } #[derive(Default)] @@ -28,8 +36,8 @@ pub mod sub_object { } #[invokable] - pub fn say_hi(&self, string: &str, number: i32) { - let s: String = string.into(); + pub fn say_hi(&self, string: &QString, number: i32) { + let s: String = string.to_string(); println!("Hi from Rust! String is {} and number is {}", s, number); } } diff --git a/examples/qml_features/src/types.rs b/examples/qml_features/src/types.rs index 3bf567c46..e270f0c06 100644 --- a/examples/qml_features/src/types.rs +++ b/examples/qml_features/src/types.rs @@ -9,7 +9,7 @@ mod types { use cxx_qt_lib::{QVariant, QVariantValue}; pub struct Data { - variant: QVariant, + variant: UniquePtr, } impl Default for Data { @@ -28,17 +28,17 @@ mod types { pub fn test_variant_property(&self, cpp: &mut CppObj) { match cpp.variant().value() { QVariantValue::Bool(b) => { - cpp.set_variant(QVariant::from(!b)); + cpp.set_variant(QVariant::from(!b).as_ref().unwrap()); } QVariantValue::I32(i) => { - cpp.set_variant(QVariant::from(i * 2)); + cpp.set_variant(QVariant::from(i * 2).as_ref().unwrap()); } _ => panic!("Incorrect variant type!"), } } #[invokable] - pub fn test_variant_invokable(&self, variant: &QVariant) -> QVariant { + pub fn test_variant_invokable(&self, variant: &QVariant) -> UniquePtr { match variant.value() { QVariantValue::Bool(b) => QVariant::from(!b), QVariantValue::I32(i) => QVariant::from(i * 2), diff --git a/examples/qml_minimal/src/lib.rs b/examples/qml_minimal/src/lib.rs index a9fdc5045..7bdeab8f6 100644 --- a/examples/qml_minimal/src/lib.rs +++ b/examples/qml_minimal/src/lib.rs @@ -12,11 +12,20 @@ mod my_object { // ANCHOR_END: book_bridge_macro // ANCHOR: book_data_struct - #[derive(Default)] pub struct Data { number: i32, - string: String, + string: UniquePtr, } + + impl Default for Data { + fn default() -> Self { + Self { + number: 0, + string: QString::from_str(""), + } + } + } + // ANCHOR_END: book_data_struct // ANCHOR: book_rustobj_struct @@ -32,7 +41,7 @@ mod my_object { } #[invokable] - pub fn say_hi(&self, string: &str, number: i32) { + pub fn say_hi(&self, string: &QString, number: i32) { println!( "Hi from Rust! String is '{}' and number is {}", string, number diff --git a/examples/qml_with_threaded_logic/src/lib.rs b/examples/qml_with_threaded_logic/src/lib.rs index 9a19022e1..297b42bbe 100644 --- a/examples/qml_with_threaded_logic/src/lib.rs +++ b/examples/qml_with_threaded_logic/src/lib.rs @@ -24,15 +24,15 @@ mod website { } pub struct Data { - url: String, - title: String, + url: UniquePtr, + title: UniquePtr, } impl Default for Data { fn default() -> Self { Self { - url: "known".to_owned(), - title: "Press refresh to get a title...".to_owned(), + url: QString::from_str("known"), + title: QString::from_str("Press refresh to get a title..."), } } } @@ -58,9 +58,9 @@ mod website { impl RustObj { #[invokable] pub fn change_url(&self, cpp: &mut CppObj) { - let url = cpp.url(); + let url = cpp.url().to_string(); let new_url = if url == "known" { "unknown" } else { "known" }; - cpp.set_url(new_url); + cpp.set_url(QString::from_str(new_url).as_ref().unwrap()); } #[invokable] @@ -74,9 +74,9 @@ mod website { return; } - cpp.set_title("Loading..."); + cpp.set_title(QString::from_str("Loading...").as_ref().unwrap()); - let url = cpp.url(); + let url = cpp.url().to_string(); // ANCHOR: book_cpp_update_requester // Retrieve the update requester from the CppObj let update_requester = cpp.update_requester(); @@ -107,7 +107,7 @@ mod website { fn process_event(&mut self, event: &Event, cpp: &mut CppObj) { match event { Event::TitleArrived(title) => { - cpp.set_title(title); + cpp.set_title(QString::from_str(title).as_ref().unwrap()); self.loading.store(false, Ordering::Relaxed); } } diff --git a/tests/basic_cxx_qt/src/data.rs b/tests/basic_cxx_qt/src/data.rs index e4cc3668b..0c172e63c 100644 --- a/tests/basic_cxx_qt/src/data.rs +++ b/tests/basic_cxx_qt/src/data.rs @@ -5,20 +5,46 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 // ANCHOR: book_macro_code +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, Serialize)] +pub struct DataSerde { + number: i32, + string: String, +} + +impl From for DataSerde { + fn from(value: Data) -> DataSerde { + DataSerde { + number: value.number, + string: value.string.to_string(), + } + } +} + #[cxx_qt::bridge] mod my_data { - use serde::{Deserialize, Serialize}; + use super::DataSerde; - #[derive(Deserialize, Serialize)] pub struct Data { - number: i32, - string: String, + pub number: i32, + pub string: UniquePtr, } impl Default for Data { fn default() -> Self { let string = r#"{"number": 4, "string": "Hello World!"}"#; - serde_json::from_str(string).unwrap() + let data_serde: DataSerde = serde_json::from_str(string).unwrap(); + data_serde.into() + } + } + + impl From for Data { + fn from(value: DataSerde) -> Data { + Data { + number: value.number, + string: QString::from_str(&value.string), + } } } @@ -27,16 +53,18 @@ mod my_data { impl RustObj { #[invokable] - pub fn as_json_str(&self, cpp: &mut CppObj) -> String { + pub fn as_json_str(&self, cpp: &mut CppObj) -> UniquePtr { let data = Data::from(cpp); - serde_json::to_string(&data).unwrap() + let data_serde = DataSerde::from(data); + let data_string = serde_json::to_string(&data_serde).unwrap(); + QString::from_str(&data_string) } #[invokable] pub fn grab_values(&self, cpp: &mut CppObj) { let string = r#"{"number": 2, "string": "Goodbye!"}"#; - let data: Data = serde_json::from_str(string).unwrap(); - cpp.grab_values_from_data(data); + let data_serde: DataSerde = serde_json::from_str(string).unwrap(); + cpp.grab_values_from_data(data_serde.into()); } } } diff --git a/tests/basic_cxx_qt/src/lib.rs b/tests/basic_cxx_qt/src/lib.rs index 63c20319d..c7fab2e24 100644 --- a/tests/basic_cxx_qt/src/lib.rs +++ b/tests/basic_cxx_qt/src/lib.rs @@ -10,13 +10,21 @@ mod types; #[cxx_qt::bridge] mod my_object { - #[derive(Default)] pub struct Data { number: i32, - string: String, + string: UniquePtr, sub: crate::sub::cxx_qt_sub_object::CppObj, } + impl Default for Data { + fn default() -> Self { + Self { + number: 0, + string: QString::from_str(""), + } + } + } + #[derive(Default)] pub struct RustObj { update_call_count: i32, @@ -41,7 +49,7 @@ mod my_object { } #[invokable] - pub fn say_hi(&self, string: &str, number: i32) { + pub fn say_hi(&self, string: &QString, number: i32) { println!( "Hi from Rust! String is {} and number is {}", string, number diff --git a/tests/basic_cxx_qt/src/sub.rs b/tests/basic_cxx_qt/src/sub.rs index 202699516..9dd069041 100644 --- a/tests/basic_cxx_qt/src/sub.rs +++ b/tests/basic_cxx_qt/src/sub.rs @@ -6,10 +6,18 @@ #[cxx_qt::bridge] pub mod sub_object { - #[derive(Default)] pub struct Data { number: i32, - string: String, + string: UniquePtr, + } + + impl Default for Data { + fn default() -> Self { + Self { + number: 0, + string: QString::from_str(""), + } + } } #[derive(Default)] @@ -28,7 +36,7 @@ pub mod sub_object { } #[invokable] - pub fn say_hi(&self, string: &str, number: i32) { + pub fn say_hi(&self, string: &QString, number: i32) { println!( "Hi from Rust! String is {} and number is {}", string, number diff --git a/tests/qt_types_standalone/src/lib.rs b/tests/qt_types_standalone/src/lib.rs index 7f319b5fb..8ea758e10 100644 --- a/tests/qt_types_standalone/src/lib.rs +++ b/tests/qt_types_standalone/src/lib.rs @@ -6,10 +6,9 @@ use core::pin::Pin; use cxx_qt_lib::{ - QColor, QDate, QDateTime, QPoint, QPointF, QRect, QRectF, QSize, QSizeF, QTime, QUrl, QVariant, - QVariantValue, ToUniquePtr, + QColor, QDate, QDateTime, QPoint, QPointF, QRect, QRectF, QSize, QSizeF, QString, QTime, QUrl, + QVariant, QVariantValue, }; -use std::str::FromStr; #[cxx::bridge] mod ffi { @@ -48,12 +47,12 @@ mod ffi { include!("cxx-qt-lib/include/qt_types.h"); include!("bridge.h"); - type QColor = cxx_qt_lib::QColorCpp; + type QColor = cxx_qt_lib::QColor; type QDate = cxx_qt_lib::QDate; - type QDateTime = cxx_qt_lib::QDateTimeCpp; - type QString = cxx_qt_lib::QStringCpp; - type QUrl = cxx_qt_lib::QUrlCpp; - type QVariant = cxx_qt_lib::QVariantCpp; + type QDateTime = cxx_qt_lib::QDateTime; + type QString = cxx_qt_lib::QString; + type QUrl = cxx_qt_lib::QUrl; + type QVariant = cxx_qt_lib::QVariant; type QSize = cxx_qt_lib::QSize; type QSizeF = cxx_qt_lib::QSizeF; type QPoint = cxx_qt_lib::QPoint; @@ -141,38 +140,38 @@ use ffi::VariantTest; fn can_construct_qstring(slice: bool) -> bool { if slice { - ffi::test_constructed_qstring(&"String constructed by Rust".to_unique_ptr()) + ffi::test_constructed_qstring(&QString::from_str("String constructed by Rust")) } else { let rs_string = "String constructed by Rust".to_owned(); - ffi::test_constructed_qstring(&rs_string.to_unique_ptr()) + ffi::test_constructed_qstring(&QString::from_str(&rs_string)) } } -fn can_read_qstring(s: &cxx_qt_lib::QStringCpp) -> bool { - let rs = s.to_rust(); +fn can_read_qstring(s: &cxx_qt_lib::QString) -> bool { + let rs = s.to_string(); rs == "String constructed by C++" } -fn modify_qstring(s: Pin<&mut cxx_qt_lib::QStringCpp>) { - ffi::assign_to_qstring(s, &"Updated string value".to_unique_ptr()); +fn modify_qstring(s: Pin<&mut cxx_qt_lib::QString>) { + ffi::assign_to_qstring(s, &QString::from_str("Updated string value")); } fn can_handle_qstring_change() -> bool { let long_s = "Very very long string that is hopefully long enough to allocate and get Valgrind's attention :)"; - let long_s_ptr = long_s.to_unique_ptr(); + let long_s_ptr = QString::from_str(long_s); - let mut short_s_ptr = "Short string".to_unique_ptr(); + let mut short_s_ptr = QString::from_str("Short string"); ffi::assign_to_qstring(short_s_ptr.pin_mut(), &long_s_ptr); - short_s_ptr.to_rust() == long_s + short_s_ptr.to_string() == long_s } -fn make_color(test: ColorTest) -> cxx::UniquePtr { +fn make_color(test: ColorTest) -> cxx::UniquePtr { match test { - ColorTest::Rgb_Red => QColor::from_rgba(255, 0, 0, 255).to_unique_ptr(), - ColorTest::Rgb_Green => QColor::from_rgba(0, 255, 0, 255).to_unique_ptr(), - ColorTest::Rgb_Blue => QColor::from_rgba(0, 0, 255, 255).to_unique_ptr(), - ColorTest::Rgb_Transparent => QColor::from_rgba(0, 0, 0, 0).to_unique_ptr(), + ColorTest::Rgb_Red => QColor::from_rgba(255, 0, 0, 255), + ColorTest::Rgb_Green => QColor::from_rgba(0, 255, 0, 255), + ColorTest::Rgb_Blue => QColor::from_rgba(0, 0, 255, 255), + ColorTest::Rgb_Transparent => QColor::from_rgba(0, 0, 0, 0), _others => panic!("Unsupported test: {}", test.repr), } } @@ -182,8 +181,7 @@ fn can_construct_qcolor(test: ColorTest) -> bool { ffi::test_constructed_qcolor(&color, test) } -fn can_read_qcolor(c: &cxx_qt_lib::QColorCpp, test: ColorTest) -> bool { - let color = c.to_rust(); +fn can_read_qcolor(color: &cxx_qt_lib::QColor, test: ColorTest) -> bool { match test { ColorTest::Rgb_Red => { color.alpha() == 255 && color.red() == 255 && color.green() == 0 && color.blue() == 0 @@ -202,12 +200,11 @@ fn can_read_qcolor(c: &cxx_qt_lib::QColorCpp, test: ColorTest) -> bool { } fn can_construct_qdatetime(date: &QDate, time: &QTime) -> bool { - let dt = QDateTime::from_date_and_time(date, time).to_unique_ptr(); + let dt = QDateTime::from_date_and_time(date, time); ffi::test_constructed_qdatetime(&dt, date, time) } -fn can_read_qdatetime(dt: &cxx_qt_lib::QDateTimeCpp, date: &QDate, time: &QTime) -> bool { - let dt = dt.to_rust(); +fn can_read_qdatetime(dt: &cxx_qt_lib::QDateTime, date: &QDate, time: &QTime) -> bool { dt.date().year() == date.year() && dt.date().month() == date.month() && dt.date().day() == date.day() @@ -217,45 +214,45 @@ fn can_read_qdatetime(dt: &cxx_qt_lib::QDateTimeCpp, date: &QDate, time: &QTime) && dt.time().msec() == time.msec() } -fn can_construct_qurl(test: &cxx_qt_lib::QStringCpp) -> bool { - let url = QUrl::from_str(&test.to_rust()).unwrap().to_unique_ptr(); +fn can_construct_qurl(test: &cxx_qt_lib::QString) -> bool { + let url = QUrl::from_str(&test.to_string()); - ffi::test_constructed_qurl(&url, test) + ffi::test_constructed_qurl(url.as_ref().unwrap(), test) } -fn can_read_qurl(u: &cxx_qt_lib::QUrlCpp, test: &cxx_qt_lib::QStringCpp) -> bool { - u.to_rust().string() == test.to_rust() +fn can_read_qurl(u: &cxx_qt_lib::QUrl, test: &cxx_qt_lib::QString) -> bool { + u.string() == test.to_string() } -fn make_variant(test: VariantTest) -> cxx::UniquePtr { +fn make_variant(test: VariantTest) -> cxx::UniquePtr { match test { - VariantTest::Bool => QVariant::from(true).to_unique_ptr(), - VariantTest::F32 => QVariant::from(1.23_f32).to_unique_ptr(), - VariantTest::F64 => QVariant::from(1.23_f64).to_unique_ptr(), - VariantTest::I8 => QVariant::from(12_i8).to_unique_ptr(), - VariantTest::I16 => QVariant::from(123_i16).to_unique_ptr(), - VariantTest::I32 => QVariant::from(123_i32).to_unique_ptr(), - VariantTest::QColor => QVariant::from(QColor::from_rgba(255, 0, 0, 255)).to_unique_ptr(), - VariantTest::QDate => QVariant::from(QDate::new(2022, 1, 1)).to_unique_ptr(), - VariantTest::QDateTime => QVariant::from(QDateTime::from_date_and_time( - &QDate::new(2022, 1, 1), - &QTime::new(1, 2, 3, 4), - )) - .to_unique_ptr(), - VariantTest::QPoint => QVariant::from(QPoint::new(1, 3)).to_unique_ptr(), - VariantTest::QPointF => QVariant::from(QPointF::new(1.0, 3.0)).to_unique_ptr(), - VariantTest::QRect => QVariant::from(QRect::new(123, 456, 246, 912)).to_unique_ptr(), - VariantTest::QRectF => QVariant::from(QRectF::new(1.23, 4.56, 2.46, 9.12)).to_unique_ptr(), - VariantTest::QSize => QVariant::from(QSize::new(1, 3)).to_unique_ptr(), - VariantTest::QSizeF => QVariant::from(QSizeF::new(1.0, 3.0)).to_unique_ptr(), - VariantTest::QTime => QVariant::from(QTime::new(1, 2, 3, 4)).to_unique_ptr(), + VariantTest::Bool => QVariant::from(true), + VariantTest::F32 => QVariant::from(1.23_f32), + VariantTest::F64 => QVariant::from(1.23_f64), + VariantTest::I8 => QVariant::from(12_i8), + VariantTest::I16 => QVariant::from(123_i16), + VariantTest::I32 => QVariant::from(123_i32), + VariantTest::QColor => QVariant::from(QColor::from_rgba(255, 0, 0, 255).as_ref().unwrap()), + VariantTest::QDate => QVariant::from(QDate::new(2022, 1, 1)), + VariantTest::QDateTime => QVariant::from( + QDateTime::from_date_and_time(&QDate::new(2022, 1, 1), &QTime::new(1, 2, 3, 4)) + .as_ref() + .unwrap(), + ), + VariantTest::QPoint => QVariant::from(QPoint::new(1, 3)), + VariantTest::QPointF => QVariant::from(QPointF::new(1.0, 3.0)), + VariantTest::QRect => QVariant::from(QRect::new(123, 456, 246, 912)), + VariantTest::QRectF => QVariant::from(QRectF::new(1.23, 4.56, 2.46, 9.12)), + VariantTest::QSize => QVariant::from(QSize::new(1, 3)), + VariantTest::QSizeF => QVariant::from(QSizeF::new(1.0, 3.0)), + VariantTest::QTime => QVariant::from(QTime::new(1, 2, 3, 4)), VariantTest::QUrl => { - QVariant::from(QUrl::from_str("https://github.com/KDAB").unwrap()).to_unique_ptr() + QVariant::from(QUrl::from_str("https://github.com/KDAB").as_ref().unwrap()) } - VariantTest::String => QVariant::from("Rust string".to_owned()).to_unique_ptr(), - VariantTest::U8 => QVariant::from(12_u8).to_unique_ptr(), - VariantTest::U16 => QVariant::from(123_u16).to_unique_ptr(), - VariantTest::U32 => QVariant::from(123_u32).to_unique_ptr(), + VariantTest::String => QVariant::from("Rust string".to_owned()), + VariantTest::U8 => QVariant::from(12_u8), + VariantTest::U16 => QVariant::from(123_u16), + VariantTest::U32 => QVariant::from(123_u32), _others => panic!("Unsupported test: {}", test.repr), } } @@ -265,8 +262,8 @@ fn can_construct_qvariant(test: VariantTest) -> bool { ffi::test_constructed_qvariant(&variant, test) } -fn can_read_qvariant(v: &cxx_qt_lib::QVariantCpp, test: VariantTest) -> bool { - let variant = v.to_rust().value(); +fn can_read_qvariant(v: &cxx_qt_lib::QVariant, test: VariantTest) -> bool { + let variant = v.value(); match test { VariantTest::Bool => match variant { QVariantValue::Bool(b) => !b, @@ -357,7 +354,9 @@ fn can_read_qvariant(v: &cxx_qt_lib::QVariantCpp, test: VariantTest) -> bool { _others => false, }, VariantTest::QUrl => match variant { - QVariantValue::QUrl(url) => url.string() == "https://github.com/KDAB/cxx-qt", + QVariantValue::QUrl(url) => { + url.as_ref().unwrap().string() == "https://github.com/KDAB/cxx-qt" + } _others => false, }, VariantTest::String => match variant {