cxx_qt_gen/generator/cpp/
mod.rs1mod constructor;
7pub mod cxxqttype;
8pub mod externcxxqt;
9pub mod fragment;
10pub mod inherit;
11pub mod method;
12pub mod property;
13pub mod qenum;
14pub mod qnamespace;
15pub mod qobject;
16pub mod signal;
17pub mod threading;
18
19mod utils;
20
21use std::collections::BTreeSet;
22
23use crate::generator::cpp::fragment::CppNamedType;
24use crate::naming::cpp::syn_type_to_cpp_type;
25use crate::naming::TypeNames;
26use crate::{generator::structuring, parser::Parser};
27use externcxxqt::GeneratedCppExternCxxQtBlocks;
28use qobject::GeneratedCppQObject;
29use syn::{FnArg, ForeignItemFn, Pat, PatIdent, PatType, Result};
30
31pub struct GeneratedCppBlocks {
33 pub forward_declares: Vec<String>,
35 pub includes: BTreeSet<String>,
37 pub qobjects: Vec<GeneratedCppQObject>,
39 pub extern_cxx_qt: Vec<GeneratedCppExternCxxQtBlocks>,
41}
42
43impl GeneratedCppBlocks {
44 pub fn from(parser: &Parser) -> Result<GeneratedCppBlocks> {
46 let structures = structuring::Structures::new(&parser.cxx_qt_data)?;
47
48 let mut includes = BTreeSet::new();
49
50 let mut forward_declares: Vec<_> = parser
51 .cxx_qt_data
52 .qnamespaces
53 .iter()
54 .map(|parsed_qnamespace| qnamespace::generate(parsed_qnamespace, &mut includes))
55 .collect();
56 forward_declares.extend(
57 parser
58 .cxx_qt_data
59 .qenums
60 .iter()
61 .map(|parsed_qenum| qenum::generate_declaration(parsed_qenum, &mut includes)),
62 );
63 Ok(GeneratedCppBlocks {
64 forward_declares,
65 includes,
66 qobjects: structures
67 .qobjects
68 .iter()
69 .map(|qobject| GeneratedCppQObject::from(qobject, &parser.type_names))
70 .collect::<Result<Vec<GeneratedCppQObject>>>()?,
71 extern_cxx_qt: externcxxqt::generate(
72 &parser.cxx_qt_data.extern_cxxqt_blocks,
73 &parser.type_names,
74 )?,
75 })
76 }
77}
78
79pub fn get_cpp_params(method: &ForeignItemFn, type_names: &TypeNames) -> Result<Vec<CppNamedType>> {
81 method
82 .sig
83 .inputs
84 .iter()
85 .map(|input| {
86 if let FnArg::Typed(PatType { pat, ty, .. }) = input {
88 let ident = if let Pat::Ident(PatIdent { ident, .. }) = &**pat {
89 ident
90 } else {
91 unreachable!("Unknown pattern for type, FnArg can only have Pat::Ident")
93 };
95
96 Ok(Some(CppNamedType {
97 ident: ident.to_string(),
98 ty: syn_type_to_cpp_type(ty, type_names)?,
99 }))
100 } else {
101 Ok(None)
102 }
103 })
104 .filter_map(|result| result.map_or_else(|e| Some(Err(e)), |v| v.map(Ok)))
105 .collect()
106}
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111
112 use crate::parser::Parser;
113 use syn::{parse_quote, ItemMod};
114
115 #[test]
116 fn test_generated_cpp_blocks() {
117 let module: ItemMod = parse_quote! {
118 #[cxx_qt::bridge]
119 mod ffi {
120 extern "RustQt" {
121 #[qobject]
122 type MyObject = super::MyObjectRust;
123 }
124 }
125 };
126 let parser = Parser::from(module).unwrap();
127
128 let cpp = GeneratedCppBlocks::from(&parser).unwrap();
129 assert_eq!(cpp.qobjects.len(), 1);
130 assert_eq!(cpp.qobjects[0].name.namespace(), None);
131 }
132
133 #[test]
134 fn test_generated_cpp_blocks_namespace() {
135 let module: ItemMod = parse_quote! {
136 #[cxx_qt::bridge(namespace = "cxx_qt")]
137 mod ffi {
138 extern "RustQt" {
139 #[qobject]
140 type MyObject = super::MyObjectRust;
141 }
142 }
143 };
144 let parser = Parser::from(module).unwrap();
145
146 let cpp = GeneratedCppBlocks::from(&parser).unwrap();
147 assert_eq!(cpp.qobjects[0].name.namespace(), Some("cxx_qt"));
148 }
149}