4
4
// SPDX-License-Identifier: MIT OR Apache-2.0
5
5
6
6
use crate :: generator:: cpp:: { fragment:: CppFragmentPair , GeneratedCppBlocks } ;
7
+ use crate :: writer:: cpp:: namespace_pair;
7
8
use indoc:: formatdoc;
8
9
9
10
/// Extract the header from a given CppFragmentPair
@@ -33,80 +34,104 @@ fn create_block(block: &str, items: &[&str]) -> String {
33
34
}
34
35
}
35
36
36
- /// For a given GeneratedCppBlocks write this into a C++ header
37
- pub fn write_cpp_header ( generated : & GeneratedCppBlocks ) -> String {
38
- formatdoc ! { r#"
39
- #pragma once
37
+ /// For a given GeneratedCppBlocks write the forward declare
38
+ fn forward_declare ( generated : & GeneratedCppBlocks ) -> Vec < String > {
39
+ let ( namespace_start, namespace_end) = namespace_pair ( generated) ;
40
+
41
+ generated
42
+ . qobjects
43
+ . iter ( )
44
+ . map ( |qobject| {
45
+ formatdoc ! { r#"
46
+ {namespace_start}
47
+ class {ident};
48
+ {namespace_end}
49
+ "# ,
50
+ ident = qobject. ident,
51
+ namespace_start = namespace_start,
52
+ namespace_end = namespace_end,
53
+ }
54
+ } )
55
+ . collect :: < Vec < String > > ( )
56
+ }
40
57
41
- #include <memory>
42
- #include <mutex>
58
+ /// For a given GeneratedCppBlocks write the classes
59
+ fn qobjects_header ( generated : & GeneratedCppBlocks ) -> Vec < String > {
60
+ let ( namespace_start, namespace_end) = namespace_pair ( generated) ;
43
61
44
- {namespace_start}
45
- class {ident};
46
- {namespace_end }
62
+ generated . qobjects . iter ( ) . map ( |qobject| {
63
+ formatdoc ! { r#"
64
+ {namespace_start }
47
65
48
- #include "cxx-qt-gen/include/{cxx_stem}.cxx.h"
66
+ class {ident} : public {base_class}
67
+ {{
68
+ Q_OBJECT
69
+ {metaobjects}
49
70
50
- {namespace_start}
71
+ public:
72
+ explicit {ident}(QObject* parent = nullptr);
73
+ ~{ident}();
74
+ const {rust_ident}& unsafeRust() const;
75
+ {rust_ident}& unsafeRustMut();
51
76
52
- class {ident} : public {base_class}
53
- {{
54
- Q_OBJECT
55
- {metaobjects}
77
+ {methods}
78
+ {slots}
79
+ {signals}
80
+ private:
81
+ rust::Box<{rust_ident}> m_rustObj;
82
+ std::mutex m_rustObjMutex;
83
+ bool m_initialised = false;
56
84
57
- public:
58
- explicit {ident}(QObject* parent = nullptr);
59
- ~{ident}();
60
- const {rust_ident}& unsafeRust() const;
61
- {rust_ident}& unsafeRustMut();
85
+ {members}
86
+ }};
62
87
63
- {methods}
64
- {slots}
65
- {signals}
66
- private:
67
- rust::Box<{rust_ident}> m_rustObj;
68
- std::mutex m_rustObjMutex;
69
- bool m_initialised = false;
88
+ static_assert(std::is_base_of<QObject, {ident}>::value, "{ident} must inherit from QObject");
70
89
71
- {members}
72
- }};
90
+ {namespace_end}
73
91
74
- static_assert(std::is_base_of<QObject, {ident}>::value, "{ident} must inherit from QObject");
92
+ namespace {namespace_internals} {{
93
+ std::unique_ptr<{ident}>
94
+ newCppObject();
95
+ }} // namespace {namespace_internals}
75
96
76
- {namespace_end}
97
+ Q_DECLARE_METATYPE({metatype}*)
98
+ "# ,
99
+ ident = qobject. ident,
100
+ namespace_start = namespace_start,
101
+ namespace_end = namespace_end,
102
+ namespace_internals = qobject. namespace_internals,
103
+ rust_ident = qobject. rust_ident,
104
+ base_class = qobject. base_class,
105
+ metaobjects = qobject. metaobjects. join( "\n " ) ,
106
+ methods = create_block( "public" , & qobject. methods. iter( ) . map( pair_as_header) . collect:: <Vec <& str >>( ) ) ,
107
+ slots = create_block( "public Q_SLOTS" , & qobject. slots. iter( ) . map( pair_as_header) . collect:: <Vec <& str >>( ) ) ,
108
+ signals = create_block( "Q_SIGNALS" , & qobject. signals. iter( ) . map( AsRef :: as_ref) . collect:: <Vec <& str >>( ) ) ,
109
+ members = qobject. members. join( "\n " ) ,
110
+ metatype = if generated. namespace. is_empty( ) {
111
+ qobject. ident. clone( )
112
+ } else {
113
+ format!( "{namespace}::{ident}" , namespace = generated. namespace, ident = qobject. ident)
114
+ } ,
115
+ }
116
+ } ) . collect :: < Vec < String > > ( )
117
+ }
77
118
78
- namespace {namespace_internals} {{
79
- std::unique_ptr<{ident}>
80
- newCppObject();
81
- }} // namespace {namespace_internals}
119
+ /// For a given GeneratedCppBlocks write this into a C++ header
120
+ pub fn write_cpp_header ( generated : & GeneratedCppBlocks ) -> String {
121
+ formatdoc ! { r#"
122
+ #pragma once
82
123
83
- Q_DECLARE_METATYPE({metatype}*)
124
+ #include <memory>
125
+ #include <mutex>
126
+
127
+ {forward_declare}
128
+ #include "cxx-qt-gen/include/{cxx_stem}.cxx.h"
129
+
130
+ {qobjects}
84
131
"# ,
85
132
cxx_stem = generated. cxx_stem,
86
- ident = generated. ident,
87
- namespace_start = if generated. namespace. is_empty( ) {
88
- "" . to_owned( )
89
- } else {
90
- format!( "namespace {namespace} {{" , namespace = generated. namespace)
91
- } ,
92
- namespace_end = if generated. namespace. is_empty( ) {
93
- "" . to_owned( )
94
- } else {
95
- format!( "}} // namespace {namespace}" , namespace = generated. namespace)
96
- } ,
97
- namespace_internals = generated. namespace_internals,
98
- rust_ident = generated. rust_ident,
99
- base_class = generated. base_class,
100
- metaobjects = generated. metaobjects. join( "\n " ) ,
101
- methods = create_block( "public" , & generated. methods. iter( ) . map( pair_as_header) . collect:: <Vec <& str >>( ) ) ,
102
- slots = create_block( "public Q_SLOTS" , & generated. slots. iter( ) . map( pair_as_header) . collect:: <Vec <& str >>( ) ) ,
103
- signals = create_block( "Q_SIGNALS" , & generated. signals. iter( ) . map( AsRef :: as_ref) . collect:: <Vec <& str >>( ) ) ,
104
- members = generated. members. join( "\n " ) ,
105
- metatype = if generated. namespace. is_empty( ) {
106
- generated. ident. clone( )
107
- } else {
108
- format!( "{namespace}::{ident}" , namespace = generated. namespace, ident = generated. ident)
109
- } ,
133
+ forward_declare = forward_declare( generated) . join( "\n " ) ,
134
+ qobjects = qobjects_header( generated) . join( "\n " ) ,
110
135
}
111
136
}
112
137
@@ -115,7 +140,8 @@ mod tests {
115
140
use super :: * ;
116
141
117
142
use crate :: writer:: cpp:: tests:: {
118
- create_generated_cpp, create_generated_cpp_no_namespace, expected_header,
143
+ create_generated_cpp, create_generated_cpp_multi_qobjects,
144
+ create_generated_cpp_no_namespace, expected_header, expected_header_multi_qobjects,
119
145
expected_header_no_namespace,
120
146
} ;
121
147
use indoc:: indoc;
@@ -150,6 +176,13 @@ mod tests {
150
176
assert_str_eq ! ( output, expected_header( ) ) ;
151
177
}
152
178
179
+ #[ test]
180
+ fn test_write_cpp_header_multi_qobjects ( ) {
181
+ let generated = create_generated_cpp_multi_qobjects ( ) ;
182
+ let output = write_cpp_header ( & generated) ;
183
+ assert_str_eq ! ( output, expected_header_multi_qobjects( ) ) ;
184
+ }
185
+
153
186
#[ test]
154
187
fn test_write_cpp_header_no_namespace ( ) {
155
188
let generated = create_generated_cpp_no_namespace ( ) ;
0 commit comments