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