opencv_binding_generator/writer/rust_native/
enumeration.rs

1use std::borrow::Cow;
2use std::collections::HashMap;
3
4use once_cell::sync::Lazy;
5
6use super::element::{DefaultRustNativeElement, RustElement};
7use super::RustNativeGeneratedElement;
8use crate::debug::NameDebug;
9use crate::type_ref::{FishStyle, NameStyle};
10use crate::{CompiledInterpolation, EntityElement, Enum, StrExt};
11
12impl RustElement for Enum<'_> {
13	fn rust_module(&self) -> Cow<str> {
14		DefaultRustNativeElement::rust_module(self.entity())
15	}
16
17	fn rust_name(&self, style: NameStyle) -> Cow<str> {
18		DefaultRustNativeElement::rust_name(self, self.entity(), style).into()
19	}
20
21	fn rendered_doc_comment(&self, comment_marker: &str, opencv_version: &str) -> String {
22		DefaultRustNativeElement::rendered_doc_comment(self.entity(), comment_marker, opencv_version)
23	}
24}
25
26impl RustNativeGeneratedElement for Enum<'_> {
27	fn element_safe_id(&self) -> String {
28		format!("{}-{}", self.rust_module(), self.rust_name(NameStyle::decl()))
29	}
30
31	fn gen_rust(&self, opencv_version: &str) -> String {
32		static ENUM_TPL: Lazy<CompiledInterpolation> = Lazy::new(|| include_str!("tpl/enum/enum.tpl.rs").compile_interpolation());
33
34		static CONST_TPL_SRC: &str = include_str!("tpl/enum/const.tpl.rs");
35		static CONST_TPL: Lazy<CompiledInterpolation> = Lazy::new(|| CONST_TPL_SRC.compile_interpolation());
36
37		static CONST_IGNORED_TPL_SRC: &str = include_str!("tpl/enum/const_ignored.tpl.rs");
38		static CONST_IGNORED_TPL: Lazy<CompiledInterpolation> = Lazy::new(|| CONST_IGNORED_TPL_SRC.compile_interpolation());
39
40		static FROM_CONST_TPL_SRC: &str = include_str!("tpl/enum/from_const.tpl.rs");
41		static FROM_CONST_TPL: Lazy<CompiledInterpolation> = Lazy::new(|| FROM_CONST_TPL_SRC.compile_interpolation());
42
43		static FROM_CONST_IGNORED_TPL_SRC: &str = include_str!("tpl/enum/from_const_ignored.tpl.rs");
44		static FROM_CONST_IGNORED_TPL: Lazy<CompiledInterpolation> =
45			Lazy::new(|| FROM_CONST_IGNORED_TPL_SRC.compile_interpolation());
46
47		let consts = self.consts();
48
49		let mut enum_consts = String::with_capacity(consts.len() * (CONST_IGNORED_TPL_SRC.len().max(CONST_TPL_SRC.len())) + 32);
50		let mut from_consts =
51			String::with_capacity(consts.len() * (FROM_CONST_IGNORED_TPL_SRC.len().max(FROM_CONST_TPL_SRC.len())) + 32);
52
53		let mut generated_values = HashMap::<String, Cow<str>>::with_capacity(consts.len());
54		for c in &consts {
55			let name = c.rust_leafname(FishStyle::No);
56			let value = c.value().expect("Can't get value of enum variant").to_string();
57			let duplicate_name = generated_values.get(&value).map(|s| s.as_ref());
58			let (enum_const_tpl, from_const_tpl) = if duplicate_name.is_some() {
59				(&CONST_IGNORED_TPL, &FROM_CONST_IGNORED_TPL)
60			} else {
61				(&CONST_TPL, &FROM_CONST_TPL)
62			};
63			let comment_marker = if duplicate_name.is_some() {
64				"//"
65			} else {
66				"///"
67			};
68			let doc_comment = c.rendered_doc_comment(comment_marker, opencv_version);
69
70			let inter_vars = HashMap::from([
71				("name", name.as_ref()),
72				("value", value.as_str()),
73				("doc_comment", &doc_comment),
74				("duplicate_name", duplicate_name.unwrap_or("")),
75			]);
76			enum_const_tpl.interpolate_into(&mut enum_consts, &inter_vars);
77			from_const_tpl.interpolate_into(&mut from_consts, &inter_vars);
78
79			generated_values.insert(value, name);
80		}
81
82		ENUM_TPL.interpolate(&HashMap::from([
83			("rust_local", self.rust_name(NameStyle::decl()).as_ref()),
84			("rust_full", &self.rust_name(NameStyle::ref_())),
85			("doc_comment", &self.rendered_doc_comment("///", opencv_version)),
86			("debug", &self.get_debug()),
87			("enum_consts", &enum_consts),
88			("from_consts", &from_consts),
89		]))
90	}
91}