cxx_qt_gen/generator/cpp/
inherit.rs1use indoc::formatdoc;
6
7use crate::{
8 generator::cpp::{fragment::CppFragment, qobject::GeneratedCppQObjectBlocks},
9 naming::cpp::syn_type_to_cpp_return_type,
10 naming::TypeNames,
11 parser::inherit::ParsedInheritedMethod,
12};
13
14use syn::Result;
15
16pub fn generate(
17 inherited_methods: &[&ParsedInheritedMethod],
18 base_class: &Option<String>,
19 type_names: &TypeNames,
20) -> Result<GeneratedCppQObjectBlocks> {
21 let mut result = GeneratedCppQObjectBlocks::default();
22
23 for &method in inherited_methods {
24 let return_type = syn_type_to_cpp_return_type(&method.method.sig.output, type_names)?;
25 let base_class = base_class.as_deref().unwrap_or("QObject");
29
30 result.methods.push(CppFragment::Header(formatdoc! {
31 r#"
32 template <class... Args>
33 {return_type} {wrapper_ident}(Args ...args){mutability}
34 {{
35 return {base_class}::{func_ident}(args...);
36 }}"#,
37 mutability = if method.mutable { "" } else { " const" },
38 func_ident = method.name.cxx_unqualified(),
39 wrapper_ident = method.wrapper_ident(),
40 return_type = return_type.unwrap_or_else(|| "void".to_string()),
41 base_class = base_class
42 }));
43 }
44
45 Ok(result)
46}
47
48#[cfg(test)]
49mod tests {
50 use pretty_assertions::assert_str_eq;
51 use syn::{parse_quote, ForeignItemFn};
52
53 use super::*;
54 use crate::generator::cpp::property::tests::require_header;
55 use crate::parser::inherit::ParsedInheritedMethod;
56 use crate::parser::CaseConversion;
57
58 fn generate_from_foreign(
59 method: ForeignItemFn,
60 base_class: Option<&str>,
61 ) -> Result<GeneratedCppQObjectBlocks> {
62 let method = ParsedInheritedMethod::parse(method, CaseConversion::none())?;
63 let inherited_methods = vec![&method];
64 let base_class = base_class.map(|s| s.to_owned());
65 generate(&inherited_methods, &base_class, &TypeNames::default())
66 }
67
68 fn assert_generated_eq(expected: &str, generated: &GeneratedCppQObjectBlocks) {
69 assert_eq!(generated.methods.len(), 1);
70 let header = require_header(&generated.methods[0]).unwrap();
71 assert_str_eq!(header, expected);
72 }
73
74 #[test]
75 fn test_immutable() {
76 let generated = generate_from_foreign(
77 parse_quote! {
78 fn test(self: &T, a: B, b: C);
79 },
80 Some("TestBaseClass"),
81 )
82 .unwrap();
83
84 assert_generated_eq(
85 indoc::indoc! {"
86 template <class... Args>
87 void testCxxQtInherit(Args ...args) const
88 {
89 return TestBaseClass::test(args...);
90 }"
91 },
92 &generated,
93 );
94 }
95
96 #[test]
97 fn test_mutable() {
98 let generated = generate_from_foreign(
99 parse_quote! {
100 fn test(self: Pin<&mut T>);
101 },
102 Some("TestBaseClass"),
103 )
104 .unwrap();
105
106 assert_generated_eq(
107 indoc::indoc! {"
108 template <class... Args>
109 void testCxxQtInherit(Args ...args)
110 {
111 return TestBaseClass::test(args...);
112 }"
113 },
114 &generated,
115 );
116 }
117
118 #[test]
119 fn test_default_base_class() {
120 let generated = generate_from_foreign(
121 parse_quote! {
122 fn test(self: &T);
123 },
124 None,
125 )
126 .unwrap();
127
128 assert_generated_eq(
129 indoc::indoc! {"
130 template <class... Args>
131 void testCxxQtInherit(Args ...args) const
132 {
133 return QObject::test(args...);
134 }"
135 },
136 &generated,
137 );
138 }
139}