diff --git a/crates/cxx-qt-gen/src/generator/rust/constructor.rs b/crates/cxx-qt-gen/src/generator/rust/constructor.rs new file mode 100644 index 000000000..5a567cd58 --- /dev/null +++ b/crates/cxx-qt-gen/src/generator/rust/constructor.rs @@ -0,0 +1,304 @@ +// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company +// SPDX-FileContributor: Leon Matthes +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +use crate::{ + generator::{ + naming::{namespace::NamespaceName, qobject::QObjectName}, + rust::qobject::GeneratedRustQObjectBlocks, + }, + parser::constructor::Constructor, +}; + +use convert_case::{Case, Casing}; +use proc_macro2::{Span, TokenStream}; +use quote::{format_ident, quote}; +use syn::{parse_quote, Ident, Result, Type}; + +const CONSTRUCTOR_ARGUMENTS: &str = "CxxQtConstructorArguments"; +const BASE_ARGUMENTS: &str = "CxxQtConstructorBaseArguments"; +const NEW_ARGUMENTS: &str = "CxxQtConstructorNewArguments"; +const INITIALIZE_ARGUMENTS: &str = "CxxQtConstructorInitializeArguments"; + +fn map_types TokenStream>( + args: &Option>, + f: F, +) -> Vec { + args.as_ref() + .map(|args| args.iter().enumerate().map(f).collect()) + .unwrap_or_default() +} + +fn extract_arguments_from_tuple(args: &Option>, tuple_name: Ident) -> Vec { + map_types(args, |(index, _ty)| { + let arg_name = format_ident!("arg{index}"); + let index = syn::LitInt::new(index.to_string().as_str(), Span::call_site()); + quote! { + #arg_name: #tuple_name.#index + } + }) +} + +fn extract_arguments_from_struct(args: &Option>, struct_name: Ident) -> Vec { + map_types(args, |(index, _ty)| { + let arg_name = format_ident!("arg{index}"); + quote! { + #struct_name.#arg_name + } + }) +} + +fn argument_members(args: &Option>) -> Vec { + map_types(args, |(index, ty)| { + let arg_name = format_ident!("arg{index}"); + quote! { + #arg_name: #ty + } + }) +} + +fn generate_default_constructor( + qobject_idents: &QObjectName, + namespace: &NamespaceName, +) -> GeneratedRustQObjectBlocks { + let rust_struct_ident = &qobject_idents.rust_struct.rust; + let create_rs_ident = format_ident!( + "create_rs_{object_name}", + object_name = rust_struct_ident.to_string().to_case(Case::Snake) + ); + let namespace_internals = &namespace.internal; + + GeneratedRustQObjectBlocks { + cxx_mod_contents: vec![parse_quote! { + extern "Rust" { + #[cxx_name = "createRs"] + #[namespace = #namespace_internals] + fn #create_rs_ident() -> Box<#rust_struct_ident>; + } + }], + cxx_qt_mod_contents: vec![parse_quote! { + /// Generated CXX-Qt method which creates a boxed rust struct of a QObject + pub fn #create_rs_ident() -> std::boxed::Box<#rust_struct_ident> { + std::default::Default::default() + } + }], + } +} + +pub fn generate( + constructors: &[Constructor], + qobject_idents: &QObjectName, + namespace: &NamespaceName, +) -> Result { + if constructors.is_empty() { + return Ok(generate_default_constructor(qobject_idents, namespace)); + } + + let mut result = GeneratedRustQObjectBlocks::default(); + let namespace_internals = &namespace.internal; + let rust_struct_name_rust = &qobject_idents.rust_struct.rust; + let qobject_name_rust = &qobject_idents.cpp_class.rust; + + for (index, constructor) in constructors.iter().enumerate() { + let arguments_rust = format_ident!("{CONSTRUCTOR_ARGUMENTS}{rust_struct_name_rust}{index}"); + let base_arguments_rust = format_ident!("{BASE_ARGUMENTS}{rust_struct_name_rust}{index}"); + let new_arguments_rust = format_ident!("{NEW_ARGUMENTS}{rust_struct_name_rust}{index}"); + let initialize_arguments_rust = + format_ident!("{INITIALIZE_ARGUMENTS}{rust_struct_name_rust}{index}"); + + let arguments_cxx = format!("{CONSTRUCTOR_ARGUMENTS}{index}"); + let base_arguments_cxx = format!("{BASE_ARGUMENTS}{index}"); + let new_arguments_cxx = format!("{NEW_ARGUMENTS}{index}"); + let initialize_arguments_cxx = format!("{INITIALIZE_ARGUMENTS}{index}"); + + let base_argument_members = argument_members(&constructor.items.base_arguments); + let new_argument_members = argument_members(&constructor.items.new_arguments); + let initialize_argument_members = argument_members(&constructor.items.initialize_arguments); + + let new_rust = format_ident!("new_rs_{rust_struct_name_rust}_{index}"); + let new_cxx = format!("newRs{index}"); + + let initialize_rust = format_ident!("intialize_{rust_struct_name_rust}_{index}"); + let initialize_cxx = format!("initialize{index}"); + + let route_arguments_rust = format_ident!("route_arguments_{rust_struct_name_rust}_{index}"); + let route_arguemnts_cxx = format!("routeArguments{index}"); + + let argument_types = &constructor.arguments; + let empty_vec = &Vec::new(); + let base_argument_types = constructor + .items + .base_arguments + .as_ref() + .unwrap_or(empty_vec); + let new_argument_types = &constructor + .items + .new_arguments + .as_ref() + .unwrap_or(empty_vec); + let initialize_argument_types = &constructor + .items + .initialize_arguments + .as_ref() + .unwrap_or(empty_vec); + + let passthrough_items = &constructor.items.passthrough; + + let route_arguments_parameters: Vec = constructor + .arguments + .iter() + .enumerate() + .map(|(index, ty)| { + let name = format_ident!("arg{index}"); + quote! { #name: #ty } + }) + .collect(); + + let assign_arguments = constructor + .arguments + .iter() + .enumerate() + .map(|(index, _ty)| { + let name = format_ident!("arg{index}"); + quote! { #name } + }) + .collect::>(); + + let init_new_arguments = extract_arguments_from_tuple( + &constructor.items.new_arguments, + format_ident!("new_arguments"), + ); + let init_initialize_arguments = extract_arguments_from_tuple( + &constructor.items.initialize_arguments, + format_ident!("initialize_arguments"), + ); + let init_base_arguments = extract_arguments_from_tuple( + &constructor.items.base_arguments, + format_ident!("base_arguments"), + ); + + let extract_new_arguments = extract_arguments_from_struct( + &constructor.items.new_arguments, + format_ident!("new_arguments"), + ); + + let extract_initialize_arguments = extract_arguments_from_struct( + &constructor.items.initialize_arguments, + format_ident!("initialize_arguments"), + ); + + result.cxx_mod_contents.append(&mut vec![ + parse_quote! { + #[namespace = #namespace_internals] + #[cxx_name = #arguments_cxx] + #[doc(hidden)] + struct #arguments_rust { + baseArguments: #base_arguments_rust, + newArguments: #new_arguments_rust, + initializeArguments: #initialize_arguments_rust, + } + }, + parse_quote! { + #[namespace = #namespace_internals] + #[cxx_name = #base_arguments_cxx] + #[doc(hidden)] + struct #base_arguments_rust { + #(#base_argument_members,)* + notEmpty: i8 // Make sure there's always at least one struct member, as CXX + // doesn't support empty shared structs. + } + }, + parse_quote! { + #[namespace = #namespace_internals] + #[cxx_name = #new_arguments_cxx] + #[doc(hidden)] + struct #new_arguments_rust { + #(#new_argument_members,)* + notEmpty: i8 // Make sure there's always at least one struct member, as CXX + // doesn't support empty shared structs. + } + }, + parse_quote! { + #[namespace = #namespace_internals] + #[cxx_name = #initialize_arguments_cxx] + #[doc(hidden)] + struct #initialize_arguments_rust { + #(#initialize_argument_members,)* + notEmpty: i8 // Make sure there's always at least one struct member, as CXX + // doesn't support empty shared structs. + } + }, + parse_quote! { + extern "Rust" { + #[namespace = #namespace_internals] + #[cxx_name = #route_arguemnts_cxx] + // This function needs to marked unsafe, as some arguments may be pointers. + unsafe fn #route_arguments_rust(#(#route_arguments_parameters),*) -> #arguments_rust; + + #[namespace = #namespace_internals] + #[cxx_name = #new_cxx] + fn #new_rust(args: #new_arguments_rust) -> Box<#rust_struct_name_rust>; + + #[namespace = #namespace_internals] + #[cxx_name = #initialize_cxx] + fn #initialize_rust(qobject: Pin<&mut #qobject_name_rust>, args: #initialize_arguments_rust); + } + }, + ]); + result.cxx_qt_mod_contents.append(&mut vec![parse_quote! { + #[doc(hidden)] + pub fn #route_arguments_rust(#(#route_arguments_parameters),*) -> #arguments_rust { + // these won't be used if any of them don't have any members + #[allow(unused_variable)] + let ( + new_arguments, + base_arguments, + initialize_arguments + ) = <#qobject_name_rust as cxx_qt::Constructor<(#(#argument_types,)*)>> + ::route_arguments((#(#assign_arguments,)*)); + #arguments_rust { + baseArguments: #base_arguments_rust { + #(#init_base_arguments,)* + notEmpty: 0 + }, + initializeArguments: #initialize_arguments_rust { + #(#init_initialize_arguments,)* + notEmpty: 0 + }, + newArguments: #new_arguments_rust { + #(#init_new_arguments,)* + notEmpty: 0 + }, + } + } + }, + parse_quote! { + #[doc(hidden)] + pub fn #new_rust(new_arguments: #new_arguments_rust) -> Box<#rust_struct_name_rust> { + let new_arguments = (#(#extract_new_arguments,)*); + Box::new(<#qobject_name_rust as cxx_qt::Constructor<(#(#argument_types,)*)>>::new(new_arguments)) + } + }, + parse_quote! { + #[doc(hidden)] + pub fn #initialize_rust( + qobject: Pin<&mut #qobject_name_rust>, + initialize_arguments: #initialize_arguments_rust + ) { + let initialize_arguments = (#(#extract_initialize_arguments,)*); + <#qobject_name_rust as cxx_qt::Constructor<(#(#argument_types,)*)>>::initialize(qobject, initialize_arguments) + } + }, + parse_quote! { + impl cxx_qt::Constructor<(#(#argument_types,)*)> for #qobject_name_rust { + type NewArguments = (#(#new_argument_types,)*); + type InitializeArguments = (#(#initialize_argument_types,)*); + type BaseArguments = (#(#base_argument_types,)*); + + #(#passthrough_items)* + } + }]) + } + Ok(result) +} diff --git a/crates/cxx-qt-gen/src/generator/rust/mod.rs b/crates/cxx-qt-gen/src/generator/rust/mod.rs index 746fa12da..f7dd4cb8c 100644 --- a/crates/cxx-qt-gen/src/generator/rust/mod.rs +++ b/crates/cxx-qt-gen/src/generator/rust/mod.rs @@ -3,6 +3,7 @@ // // SPDX-License-Identifier: MIT OR Apache-2.0 +pub mod constructor; pub mod field; pub mod fragment; pub mod inherit; diff --git a/crates/cxx-qt-gen/src/generator/rust/qobject.rs b/crates/cxx-qt-gen/src/generator/rust/qobject.rs index bd8f87a2a..0fa7220b7 100644 --- a/crates/cxx-qt-gen/src/generator/rust/qobject.rs +++ b/crates/cxx-qt-gen/src/generator/rust/qobject.rs @@ -7,7 +7,7 @@ use crate::{ generator::{ naming::{namespace::NamespaceName, qobject::QObjectName}, rust::{ - field::generate_rust_fields, fragment::RustFragmentPair, inherit, + constructor, field::generate_rust_fields, fragment::RustFragmentPair, inherit, invokable::generate_rust_invokables, property::generate_rust_properties, signals::generate_rust_signals, threading, }, @@ -136,6 +136,12 @@ impl GeneratedRustQObject { }); } + generated.blocks.append(&mut constructor::generate( + &qobject.constructors, + &qobject_idents, + &namespace_idents, + )?); + Ok(generated) } } @@ -262,7 +268,7 @@ mod tests { let rust = GeneratedRustQObject::from(parser.cxx_qt_data.qobjects.values().next().unwrap()) .unwrap(); - assert_eq!(rust.blocks.cxx_mod_contents.len(), 3); + assert_eq!(rust.blocks.cxx_mod_contents.len(), 4); assert_tokens_eq( &rust.blocks.cxx_mod_contents[0], quote! { @@ -295,5 +301,15 @@ mod tests { } }, ); + assert_tokens_eq( + &rust.blocks.cxx_mod_contents[3], + quote! { + extern "Rust" { + #[cxx_name = "createRs"] + #[namespace = "cxx_qt::cxx_qt_my_object"] + fn create_rs_my_object() -> Box; + } + }, + ); } } diff --git a/crates/cxx-qt-gen/src/writer/rust/mod.rs b/crates/cxx-qt-gen/src/writer/rust/mod.rs index 79487b6c9..5eb55b8ff 100644 --- a/crates/cxx-qt-gen/src/writer/rust/mod.rs +++ b/crates/cxx-qt-gen/src/writer/rust/mod.rs @@ -4,27 +4,13 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 use crate::generator::rust::{qobject::GeneratedRustQObject, GeneratedRustBlocks}; -use convert_case::{Case, Casing}; use proc_macro2::TokenStream; use quote::{format_ident, quote, ToTokens}; -use syn::Ident; - -/// Mangle an input name with an object name -/// -/// For now we need to do this to avoid free Rust methods from colliding -/// Once static methods are possible in CXX this could be removed -/// https://github.com/dtolnay/cxx/issues/447 -fn mangle(name: &str, object: &Ident) -> Ident { - format_ident!("{}", format!("{name}_{object}").to_case(Case::Snake)) -} /// Return common blocks for CXX bridge which the C++ writer adds as well fn cxx_bridge_common_blocks(qobject: &GeneratedRustQObject) -> Vec { let cpp_struct_ident = &qobject.cpp_struct_ident; let rust_struct_ident = &qobject.rust_struct_ident; - let namespace_internals = &qobject.namespace_internals; - - let create_rs_ident = mangle("create_rs", rust_struct_ident); vec![ quote! { @@ -41,13 +27,6 @@ fn cxx_bridge_common_blocks(qobject: &GeneratedRustQObject) -> Vec unsafe fn cxx_qt_ffi_rust_mut(self: Pin<&mut #cpp_struct_ident>) -> Pin<&mut #rust_struct_ident>; } }, - quote! { - extern "Rust" { - #[cxx_name = "createRs"] - #[namespace = #namespace_internals] - fn #create_rs_ident() -> Box<#rust_struct_ident>; - } - }, ] } @@ -55,29 +34,20 @@ fn cxx_bridge_common_blocks(qobject: &GeneratedRustQObject) -> Vec fn cxx_qt_common_blocks(qobject: &GeneratedRustQObject) -> Vec { let cpp_struct_ident = &qobject.cpp_struct_ident; let rust_struct_ident = &qobject.rust_struct_ident; - let create_rs_ident = mangle("create_rs", rust_struct_ident); - - vec![ - quote! { - impl cxx_qt::CxxQtType for #cpp_struct_ident { - type Rust = #rust_struct_ident; - fn rust(&self) -> &Self::Rust { - self.cxx_qt_ffi_rust() - } + vec![quote! { + impl cxx_qt::CxxQtType for #cpp_struct_ident { + type Rust = #rust_struct_ident; - unsafe fn rust_mut(self: core::pin::Pin<&mut Self>) -> Pin<&mut Self::Rust> { - self.cxx_qt_ffi_rust_mut() - } + fn rust(&self) -> &Self::Rust { + self.cxx_qt_ffi_rust() } - }, - quote! { - /// Generated CXX-Qt method which creates a boxed rust struct of a QObject - pub fn #create_rs_ident() -> std::boxed::Box<#rust_struct_ident> { - std::default::Default::default() + + unsafe fn rust_mut(self: core::pin::Pin<&mut Self>) -> Pin<&mut Self::Rust> { + self.cxx_qt_ffi_rust_mut() } - }, - ] + } + }] } /// For a given GeneratedRustBlocks write this into a Rust TokenStream @@ -387,12 +357,6 @@ mod tests { #[doc(hidden)] unsafe fn cxx_qt_ffi_rust_mut(self: Pin<&mut MyObjectQt>) -> Pin<&mut MyObject>; } - - extern "Rust" { - #[cxx_name = "createRs"] - #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] - fn create_rs_my_object() -> Box; - } } use self::cxx_qt_ffi::*; @@ -425,11 +389,6 @@ mod tests { } } - /// Generated CXX-Qt method which creates a boxed rust struct of a QObject - pub fn create_rs_my_object() -> std::boxed::Box { - std::default::Default::default() - } - /// Generated CXX-Qt module containing type alias to the C++ types of the QObjects pub mod qobject { #[doc = "The C++ type for the QObject "] @@ -492,12 +451,6 @@ mod tests { #[doc(hidden)] unsafe fn cxx_qt_ffi_rust_mut(self: Pin<&mut FirstObjectQt>) -> Pin<&mut FirstObject>; } - - extern "Rust" { - #[cxx_name = "createRs"] - #[namespace = "cxx_qt::cxx_qt_first_object"] - fn create_rs_first_object() -> Box; - } unsafe extern "C++" { #[cxx_name = "SecondObject"] type SecondObjectQt; @@ -519,12 +472,6 @@ mod tests { #[doc(hidden)] unsafe fn cxx_qt_ffi_rust_mut(self: Pin<&mut SecondObjectQt>) -> Pin<&mut SecondObject>; } - - extern "Rust" { - #[cxx_name = "createRs"] - #[namespace = "cxx_qt::cxx_qt_second_object"] - fn create_rs_second_object() -> Box; - } } use self::cxx_qt_ffi::*; @@ -557,11 +504,6 @@ mod tests { } } - /// Generated CXX-Qt method which creates a boxed rust struct of a QObject - pub fn create_rs_first_object() -> std::boxed::Box { - std::default::Default::default() - } - #[derive(Default)] pub struct SecondObject; @@ -581,11 +523,6 @@ mod tests { } } - /// Generated CXX-Qt method which creates a boxed rust struct of a QObject - pub fn create_rs_second_object() -> std::boxed::Box { - std::default::Default::default() - } - /// Generated CXX-Qt module containing type alias to the C++ types of the QObjects pub mod qobject { #[doc = "The C++ type for the QObject "] diff --git a/crates/cxx-qt-gen/test_outputs/inheritance.rs b/crates/cxx-qt-gen/test_outputs/inheritance.rs index f021c7753..331c1905b 100644 --- a/crates/cxx-qt-gen/test_outputs/inheritance.rs +++ b/crates/cxx-qt-gen/test_outputs/inheritance.rs @@ -63,6 +63,11 @@ mod inheritance { #[cxx_name = "fetchMoreCxxQtInherit"] unsafe fn fetch_more(self: Pin<&mut MyObjectQt>, index: &QModelIndex); } + extern "Rust" { + #[cxx_name = "createRs"] + #[namespace = "cxx_qt_my_object"] + fn create_rs_my_object() -> Box; + } unsafe extern "C++" { #[cxx_name = "unsafeRust"] #[doc(hidden)] @@ -73,11 +78,6 @@ mod inheritance { #[doc(hidden)] unsafe fn cxx_qt_ffi_rust_mut(self: Pin<&mut MyObjectQt>) -> Pin<&mut MyObject>; } - extern "Rust" { - #[cxx_name = "createRs"] - #[namespace = "cxx_qt_my_object"] - fn create_rs_my_object() -> Box; - } } use self::cxx_qt_inheritance::*; mod cxx_qt_inheritance { @@ -139,6 +139,10 @@ mod cxx_qt_inheritance { } } impl cxx_qt::Locking for MyObjectQt {} + #[doc = r" Generated CXX-Qt method which creates a boxed rust struct of a QObject"] + pub fn create_rs_my_object() -> std::boxed::Box { + std::default::Default::default() + } impl cxx_qt::CxxQtType for MyObjectQt { type Rust = MyObject; fn rust(&self) -> &Self::Rust { @@ -148,10 +152,6 @@ mod cxx_qt_inheritance { self.cxx_qt_ffi_rust_mut() } } - #[doc = r" Generated CXX-Qt method which creates a boxed rust struct of a QObject"] - pub fn create_rs_my_object() -> std::boxed::Box { - std::default::Default::default() - } #[doc = r" Generated CXX-Qt module containing type alias to the C++ types of the QObjects"] pub mod qobject { #[doc = "The C++ type for the QObject "] diff --git a/crates/cxx-qt-gen/test_outputs/invokables.rs b/crates/cxx-qt-gen/test_outputs/invokables.rs index 88a9f7db7..0f505dfc7 100644 --- a/crates/cxx-qt-gen/test_outputs/invokables.rs +++ b/crates/cxx-qt-gen/test_outputs/invokables.rs @@ -107,6 +107,52 @@ mod ffi { #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] type MyObjectCxxQtThreadQueuedFn; } + #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] + #[cxx_name = "CxxQtConstructorArguments0"] + #[doc(hidden)] + struct CxxQtConstructorArgumentsMyObject0 { + baseArguments: CxxQtConstructorBaseArgumentsMyObject0, + newArguments: CxxQtConstructorNewArgumentsMyObject0, + initializeArguments: CxxQtConstructorInitializeArgumentsMyObject0, + } + #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] + #[cxx_name = "CxxQtConstructorBaseArguments0"] + #[doc(hidden)] + struct CxxQtConstructorBaseArgumentsMyObject0 { + arg0: *mut QObject, + notEmpty: i8, + } + #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] + #[cxx_name = "CxxQtConstructorNewArguments0"] + #[doc(hidden)] + struct CxxQtConstructorNewArgumentsMyObject0 { + arg0: i32, + notEmpty: i8, + } + #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] + #[cxx_name = "CxxQtConstructorInitializeArguments0"] + #[doc(hidden)] + struct CxxQtConstructorInitializeArgumentsMyObject0 { + arg0: i32, + notEmpty: i8, + } + extern "Rust" { + #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] + #[cxx_name = "routeArguments0"] + unsafe fn route_arguments_MyObject_0( + arg0: i32, + arg1: *mut QObject, + ) -> CxxQtConstructorArgumentsMyObject0; + #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] + #[cxx_name = "newRs0"] + fn new_rs_MyObject_0(args: CxxQtConstructorNewArgumentsMyObject0) -> Box; + #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] + #[cxx_name = "initialize0"] + fn intialize_MyObject_0( + qobject: Pin<&mut MyObjectQt>, + args: CxxQtConstructorInitializeArgumentsMyObject0, + ); + } unsafe extern "C++" { #[cxx_name = "unsafeRust"] #[doc(hidden)] @@ -117,11 +163,6 @@ mod ffi { #[doc(hidden)] unsafe fn cxx_qt_ffi_rust_mut(self: Pin<&mut MyObjectQt>) -> Pin<&mut MyObject>; } - extern "Rust" { - #[cxx_name = "createRs"] - #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] - fn create_rs_my_object() -> Box; - } } use self::cxx_qt_ffi::*; mod cxx_qt_ffi { @@ -284,6 +325,52 @@ mod cxx_qt_ffi { inner: std::boxed::Box) + Send>, } impl cxx_qt::Locking for MyObjectQt {} + #[doc(hidden)] + pub fn route_arguments_MyObject_0( + arg0: i32, + arg1: *mut QObject, + ) -> CxxQtConstructorArgumentsMyObject0 { + #[allow(unused_variable)] + let (new_arguments, base_arguments, initialize_arguments) = + >::route_arguments((arg0, arg1)); + CxxQtConstructorArgumentsMyObject0 { + baseArguments: CxxQtConstructorBaseArgumentsMyObject0 { + arg0: base_arguments.0, + notEmpty: 0, + }, + initializeArguments: CxxQtConstructorInitializeArgumentsMyObject0 { + arg0: initialize_arguments.0, + notEmpty: 0, + }, + newArguments: CxxQtConstructorNewArgumentsMyObject0 { + arg0: new_arguments.0, + notEmpty: 0, + }, + } + } + #[doc(hidden)] + pub fn new_rs_MyObject_0( + new_arguments: CxxQtConstructorNewArgumentsMyObject0, + ) -> Box { + let new_arguments = (new_arguments.arg0,); + Box::new(>::new(new_arguments)) + } + #[doc(hidden)] + pub fn intialize_MyObject_0( + qobject: Pin<&mut MyObjectQt>, + initialize_arguments: CxxQtConstructorInitializeArgumentsMyObject0, + ) { + let initialize_arguments = (initialize_arguments.arg0,); + >::initialize( + qobject, + initialize_arguments, + ) + } + impl cxx_qt::Constructor<(i32, *mut QObject)> for MyObjectQt { + type NewArguments = (i32,); + type InitializeArguments = (i32,); + type BaseArguments = (*mut QObject,); + } impl cxx_qt::CxxQtType for MyObjectQt { type Rust = MyObject; fn rust(&self) -> &Self::Rust { @@ -293,10 +380,6 @@ mod cxx_qt_ffi { self.cxx_qt_ffi_rust_mut() } } - #[doc = r" Generated CXX-Qt method which creates a boxed rust struct of a QObject"] - pub fn create_rs_my_object() -> std::boxed::Box { - std::default::Default::default() - } #[doc = r" Generated CXX-Qt module containing type alias to the C++ types of the QObjects"] pub mod qobject { #[doc = "The C++ type for the QObject "] diff --git a/crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs b/crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs index f09f6cd4a..da64b01b8 100644 --- a/crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs +++ b/crates/cxx-qt-gen/test_outputs/passthrough_and_naming.rs @@ -113,6 +113,11 @@ pub mod ffi { conn_type: CxxQtConnectionType, ) -> CxxQtQMetaObjectConnection; } + extern "Rust" { + #[cxx_name = "createRs"] + #[namespace = "cxx_qt::multi_object::cxx_qt_my_object"] + fn create_rs_my_object() -> Box; + } unsafe extern "C++" { #[cxx_name = "unsafeRust"] #[doc(hidden)] @@ -123,11 +128,6 @@ pub mod ffi { #[doc(hidden)] unsafe fn cxx_qt_ffi_rust_mut(self: Pin<&mut MyObjectQt>) -> Pin<&mut MyObject>; } - extern "Rust" { - #[cxx_name = "createRs"] - #[namespace = "cxx_qt::multi_object::cxx_qt_my_object"] - fn create_rs_my_object() -> Box; - } unsafe extern "C++" { #[doc = "The C++ type for the QObject "] #[doc = "SecondObject"] @@ -181,6 +181,11 @@ pub mod ffi { conn_type: CxxQtConnectionType, ) -> CxxQtQMetaObjectConnection; } + extern "Rust" { + #[cxx_name = "createRs"] + #[namespace = "cxx_qt::multi_object::cxx_qt_second_object"] + fn create_rs_second_object() -> Box; + } unsafe extern "C++" { #[cxx_name = "unsafeRust"] #[doc(hidden)] @@ -191,11 +196,6 @@ pub mod ffi { #[doc(hidden)] unsafe fn cxx_qt_ffi_rust_mut(self: Pin<&mut SecondObjectQt>) -> Pin<&mut SecondObject>; } - extern "Rust" { - #[cxx_name = "createRs"] - #[namespace = "cxx_qt::multi_object::cxx_qt_second_object"] - fn create_rs_second_object() -> Box; - } } pub use self::cxx_qt_ffi::*; mod cxx_qt_ffi { @@ -320,6 +320,10 @@ mod cxx_qt_ffi { } } impl cxx_qt::Locking for MyObjectQt {} + #[doc = r" Generated CXX-Qt method which creates a boxed rust struct of a QObject"] + pub fn create_rs_my_object() -> std::boxed::Box { + std::default::Default::default() + } impl cxx_qt::CxxQtType for MyObjectQt { type Rust = MyObject; fn rust(&self) -> &Self::Rust { @@ -329,10 +333,6 @@ mod cxx_qt_ffi { self.cxx_qt_ffi_rust_mut() } } - #[doc = r" Generated CXX-Qt method which creates a boxed rust struct of a QObject"] - pub fn create_rs_my_object() -> std::boxed::Box { - std::default::Default::default() - } impl Default for SecondObject { fn default() -> Self { Self { property_name: 32 } @@ -425,6 +425,10 @@ mod cxx_qt_ffi { } } } + #[doc = r" Generated CXX-Qt method which creates a boxed rust struct of a QObject"] + pub fn create_rs_second_object() -> std::boxed::Box { + std::default::Default::default() + } impl cxx_qt::CxxQtType for SecondObjectQt { type Rust = SecondObject; fn rust(&self) -> &Self::Rust { @@ -434,10 +438,6 @@ mod cxx_qt_ffi { self.cxx_qt_ffi_rust_mut() } } - #[doc = r" Generated CXX-Qt method which creates a boxed rust struct of a QObject"] - pub fn create_rs_second_object() -> std::boxed::Box { - std::default::Default::default() - } #[doc = r" Generated CXX-Qt module containing type alias to the C++ types of the QObjects"] pub mod qobject { #[doc = "The C++ type for the QObject "] diff --git a/crates/cxx-qt-gen/test_outputs/properties.rs b/crates/cxx-qt-gen/test_outputs/properties.rs index 806239ae9..d48dd995a 100644 --- a/crates/cxx-qt-gen/test_outputs/properties.rs +++ b/crates/cxx-qt-gen/test_outputs/properties.rs @@ -71,6 +71,11 @@ mod ffi { #[rust_name = "trivial_changed"] fn trivialChanged(self: Pin<&mut MyObjectQt>); } + extern "Rust" { + #[cxx_name = "createRs"] + #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] + fn create_rs_my_object() -> Box; + } unsafe extern "C++" { #[cxx_name = "unsafeRust"] #[doc(hidden)] @@ -81,11 +86,6 @@ mod ffi { #[doc(hidden)] unsafe fn cxx_qt_ffi_rust_mut(self: Pin<&mut MyObjectQt>) -> Pin<&mut MyObject>; } - extern "Rust" { - #[cxx_name = "createRs"] - #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] - fn create_rs_my_object() -> Box; - } } use self::cxx_qt_ffi::*; mod cxx_qt_ffi { @@ -242,6 +242,10 @@ mod cxx_qt_ffi { } } impl cxx_qt::Locking for MyObjectQt {} + #[doc = r" Generated CXX-Qt method which creates a boxed rust struct of a QObject"] + pub fn create_rs_my_object() -> std::boxed::Box { + std::default::Default::default() + } impl cxx_qt::CxxQtType for MyObjectQt { type Rust = MyObject; fn rust(&self) -> &Self::Rust { @@ -251,10 +255,6 @@ mod cxx_qt_ffi { self.cxx_qt_ffi_rust_mut() } } - #[doc = r" Generated CXX-Qt method which creates a boxed rust struct of a QObject"] - pub fn create_rs_my_object() -> std::boxed::Box { - std::default::Default::default() - } #[doc = r" Generated CXX-Qt module containing type alias to the C++ types of the QObjects"] pub mod qobject { #[doc = "The C++ type for the QObject "] diff --git a/crates/cxx-qt-gen/test_outputs/signals.rs b/crates/cxx-qt-gen/test_outputs/signals.rs index 19a0cd342..bd24483ab 100644 --- a/crates/cxx-qt-gen/test_outputs/signals.rs +++ b/crates/cxx-qt-gen/test_outputs/signals.rs @@ -114,6 +114,11 @@ mod ffi { conn_type: CxxQtConnectionType, ) -> CxxQtQMetaObjectConnection; } + extern "Rust" { + #[cxx_name = "createRs"] + #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] + fn create_rs_my_object() -> Box; + } unsafe extern "C++" { #[cxx_name = "unsafeRust"] #[doc(hidden)] @@ -124,11 +129,6 @@ mod ffi { #[doc(hidden)] unsafe fn cxx_qt_ffi_rust_mut(self: Pin<&mut MyObjectQt>) -> Pin<&mut MyObject>; } - extern "Rust" { - #[cxx_name = "createRs"] - #[namespace = "cxx_qt::my_object::cxx_qt_my_object"] - fn create_rs_my_object() -> Box; - } } use self::cxx_qt_ffi::*; mod cxx_qt_ffi { @@ -254,6 +254,10 @@ mod cxx_qt_ffi { } } impl cxx_qt::Locking for MyObjectQt {} + #[doc = r" Generated CXX-Qt method which creates a boxed rust struct of a QObject"] + pub fn create_rs_my_object() -> std::boxed::Box { + std::default::Default::default() + } impl cxx_qt::CxxQtType for MyObjectQt { type Rust = MyObject; fn rust(&self) -> &Self::Rust { @@ -263,10 +267,6 @@ mod cxx_qt_ffi { self.cxx_qt_ffi_rust_mut() } } - #[doc = r" Generated CXX-Qt method which creates a boxed rust struct of a QObject"] - pub fn create_rs_my_object() -> std::boxed::Box { - std::default::Default::default() - } #[doc = r" Generated CXX-Qt module containing type alias to the C++ types of the QObjects"] pub mod qobject { #[doc = "The C++ type for the QObject "]