opencv_binding_generator/writer/rust_native/
class.rs

1mod 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 = self.cpp_name(CppNameStyle::Declaration);
41			if cpp_declname == "Vec" {
42				"VecN".into()
43			} else {
44				cpp_declname
45			}
46		}
47	}
48
49	fn rendered_doc_comment(&self, comment_marker: &str, opencv_version: &str) -> String {
50		match self {
51			&Self::Clang { entity, .. } => DefaultRustNativeElement::rendered_doc_comment(entity, comment_marker, opencv_version),
52			Self::Desc(_) => "".to_string(),
53		}
54	}
55}
56
57impl RustNativeGeneratedElement for Class<'_, '_> {
58	fn element_safe_id(&self) -> String {
59		format!("{}-{}", self.rust_module().opencv_name(), self.rust_name(NameStyle::decl()))
60	}
61
62	fn gen_rust(&self, opencv_version: &str) -> String {
63		match self.kind() {
64			ClassKind::Simple => gen::gen_simple_class(self, opencv_version),
65			ClassKind::Boxed | ClassKind::BoxedForced => gen::gen_boxed_class(self, opencv_version),
66			ClassKind::System | ClassKind::Other => "".to_string(),
67		}
68	}
69
70	fn gen_rust_externs(&self) -> String {
71		gen::extern_functions(self).iter().map(Func::gen_rust_externs).join("")
72	}
73
74	fn gen_cpp(&self) -> String {
75		gen::extern_functions(self).iter().map(Func::gen_cpp).join("")
76	}
77}
78
79pub trait ClassExt {
80	fn rust_trait_name(&self, style: NameStyle, constness: Constness) -> Cow<str>;
81	fn rust_as_raw_name(&self, constness: Constness) -> String;
82	fn rust_lifetime(&self) -> Option<Lifetime>;
83}
84
85impl ClassExt for Class<'_, '_> {
86	fn rust_trait_name(&self, style: NameStyle, constness: Constness) -> Cow<str> {
87		let mut out = self.rust_name(style);
88		if self.kind().is_trait() {
89			if constness.is_const() {
90				out.to_mut().push_str("TraitConst");
91			} else {
92				out.to_mut().push_str("Trait");
93			}
94		}
95		out
96	}
97
98	fn rust_as_raw_name(&self, constness: Constness) -> String {
99		format!(
100			"as_raw{const_qual}_{name}",
101			const_qual = constness.rust_function_name_qual(),
102			name = self.rust_name(NameStyle::Declaration)
103		)
104	}
105
106	/// Rust lifetime use by the objects of this class
107	fn rust_lifetime(&self) -> Option<Lifetime> {
108		match self {
109			Class::Clang { gen_env, .. } =>
110			{
111				#[allow(clippy::bind_instead_of_map)]
112				gen_env
113					.settings
114					.class_tweak
115					.get(self.cpp_name(CppNameStyle::Reference).as_ref())
116					.and_then(|tweak| match tweak {
117						ClassTweak::Lifetime(lt) => Some(*lt),
118					})
119			}
120			Class::Desc(_) => None,
121		}
122	}
123}
124
125pub fn rust_generate_debug_fields<'f>(field_const_methods: impl IntoIterator<Item = Func<'f, 'f>>) -> String {
126	field_const_methods
127		.into_iter()
128		.filter(|f| f.return_type_ref().kind().is_debug())
129		.filter_map(|f| {
130			f.kind().as_field_accessor().map(|(cls, _)| {
131				format!(
132					"\n\t.field(\"{name}\", &{trait_name}::{name}(self))",
133					trait_name = cls.rust_trait_name(NameStyle::ref_fish(), Constness::Const),
134					name = f.rust_leafname(FishStyle::No)
135				)
136			})
137		})
138		.join("")
139}