Skip to main content

opencv_binding_generator/writer/rust_native/
class.rs

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