opencv_binding_generator/writer/rust_native/
class.rs1mod gen;
2
3use std::borrow::Cow;
4
5use super::element::{DefaultRustNativeElement, RustElement};
6use super::RustNativeGeneratedElement;
7use crate::class::ClassKind;
8use crate::settings::ClassTweak;
9use crate::type_ref::{Constness, CppNameStyle, FishStyle, NameStyle};
10use crate::writer::rust_native::type_ref::Lifetime;
11use crate::{Class, Element, Func, IteratorExt, SupportedModule};
12
13impl RustElement for Class<'_, '_> {
14 fn rust_module(&self) -> SupportedModule {
15 match self {
16 &Self::Clang { entity, .. } => DefaultRustNativeElement::rust_module(entity),
17 Self::Desc(desc) => desc.rust_module,
18 }
19 }
20
21 fn rust_name(&self, style: NameStyle) -> Cow<'_, str> {
22 match self {
23 &Self::Clang { entity, .. } => DefaultRustNativeElement::rust_name(self, entity, style).into(),
24 Self::Desc(_) => match style {
25 NameStyle::Declaration => self.rust_leafname(FishStyle::No),
26 NameStyle::Reference(fish_style) => format!(
27 "{}::{}",
28 DefaultRustNativeElement::rust_module_reference(self),
29 self.rust_leafname(fish_style)
30 )
31 .into(),
32 },
33 }
34 }
35
36 fn rust_leafname(&self, _fish_style: FishStyle) -> Cow<'_, str> {
37 if self.string_type().is_some() {
38 "String".into()
39 } else {
40 let cpp_declname = DefaultRustNativeElement::rust_leafname(self);
41 if cpp_declname == "Vec" {
42 "VecN".into()
43 } else {
44 cpp_declname
45 }
46 }
47 }
48}
49
50impl RustNativeGeneratedElement for Class<'_, '_> {
51 fn element_safe_id(&self) -> String {
52 format!("{}-{}", self.rust_module().opencv_name(), self.rust_name(NameStyle::decl()))
53 }
54
55 fn gen_rust(&self, opencv_version: &str) -> String {
56 match self.kind() {
57 ClassKind::Simple => gen::gen_simple_class(self, opencv_version),
58 ClassKind::Boxed | ClassKind::BoxedForced => gen::gen_boxed_class(self, opencv_version),
59 ClassKind::System | ClassKind::Other => "".to_string(),
60 }
61 }
62
63 fn gen_rust_externs(&self) -> String {
64 gen::extern_functions(self).iter().map(Func::gen_rust_externs).join("")
65 }
66
67 fn gen_cpp(&self) -> String {
68 gen::extern_functions(self).iter().map(Func::gen_cpp).join("")
69 }
70}
71
72pub trait ClassExt {
73 fn rust_trait_name(&self, style: NameStyle, constness: Constness) -> Cow<'_, str>;
74 fn rust_as_raw_name(&self, constness: Constness) -> String;
75 fn rust_lifetime(&self) -> Option<Lifetime>;
76}
77
78impl ClassExt for Class<'_, '_> {
79 fn rust_trait_name(&self, style: NameStyle, constness: Constness) -> Cow<'_, str> {
80 let mut out = self.rust_name(style);
81 if self.kind().is_trait() {
82 if constness.is_const() {
83 out.to_mut().push_str("TraitConst");
84 } else {
85 out.to_mut().push_str("Trait");
86 }
87 }
88 out
89 }
90
91 fn rust_as_raw_name(&self, constness: Constness) -> String {
92 format!(
93 "as_raw{const_qual}_{name}",
94 const_qual = constness.rust_function_name_qual(),
95 name = self.rust_name(NameStyle::Declaration)
96 )
97 }
98
99 fn rust_lifetime(&self) -> Option<Lifetime> {
101 match self {
102 Class::Clang { gen_env, .. } =>
103 {
104 #[allow(clippy::bind_instead_of_map)]
105 gen_env
106 .settings
107 .class_tweak
108 .get(self.cpp_name(CppNameStyle::Reference).as_ref())
109 .and_then(|tweak| match tweak {
110 ClassTweak::Lifetime(lt) => Some(*lt),
111 })
112 }
113 Class::Desc(_) => None,
114 }
115 }
116}
117
118pub fn rust_generate_debug_fields<'f>(field_const_methods: impl IntoIterator<Item = Func<'f, 'f>>) -> String {
119 field_const_methods
120 .into_iter()
121 .filter(|f| f.return_type_ref().kind().is_debug())
122 .filter_map(|f| {
123 f.kind().as_field_accessor().map(|(cls, _)| {
124 format!(
125 "\n\t.field(\"{name}\", &{trait_name}::{name}(self))",
126 trait_name = cls.rust_trait_name(NameStyle::ref_fish(), Constness::Const),
127 name = f.rust_leafname(FishStyle::No)
128 )
129 })
130 })
131 .join("")
132}