Skip to content

Commit e30aaf6

Browse files
committed
Add property renaming machinery
1 parent dd1577b commit e30aaf6

File tree

5 files changed

+150
-150
lines changed

5 files changed

+150
-150
lines changed

binding-generator/src/class.rs

Lines changed: 109 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -414,129 +414,128 @@ impl<'tu, 'ge> Class<'tu, 'ge> {
414414
'ge: 'f,
415415
{
416416
match self {
417-
&Self::Clang { .. } => {
418-
let mut out = Vec::with_capacity(fields.size_hint().1.map_or(8, |x| x * 2));
419-
out.extend(fields.flat_map(|fld| {
420-
iter::from_fn({
421-
let doc_comment = Rc::from(fld.doc_comment());
422-
let def_loc = fld.file_line_name().location;
423-
let rust_module = fld.rust_module();
424-
let mut fld_type_ref = fld.type_ref();
425-
let fld_type_kind = fld_type_ref.kind();
426-
if fld_type_kind
427-
.as_pointer()
428-
.map_or(false, |inner| inner.kind().as_primitive().is_some())
429-
&& !fld_type_kind.is_char_ptr_string(fld_type_ref.type_hint())
430-
{
431-
fld_type_ref.to_mut().set_type_hint(TypeRefTypeHint::PrimitivePtrAsRaw);
432-
} else if fld_type_kind.as_class().map_or(false, |cls| cls.kind().is_trait()) {
433-
fld_type_ref.to_mut().set_type_hint(TypeRefTypeHint::TraitClassConcrete);
434-
}
435-
let fld_type_kind = fld_type_ref.kind();
436-
let fld_type_ref_return_as_naked = fld_type_kind.return_as_naked(fld_type_ref.type_hint());
437-
let return_kind = ReturnKind::infallible(fld_type_ref_return_as_naked);
438-
let fld_const = fld.constness();
439-
let passed_by_ref = fld_type_kind.can_return_as_direct_reference();
440-
let (mut read_const_yield, mut read_mut_yield) = if passed_by_ref && fld_const.is_mut() {
441-
let read_const_func = if constness_filter.map_or(true, |c| c.is_const()) {
442-
Some(Func::new_desc(
443-
FuncDesc::new(
444-
FuncKind::FieldAccessor(self.clone(), fld.clone()),
445-
Constness::Const,
446-
return_kind,
447-
fld.cpp_name(CppNameStyle::Reference),
448-
rust_module.clone(),
449-
[],
450-
fld_type_ref.as_ref().clone().with_inherent_constness(Constness::Const),
451-
)
452-
.def_loc(def_loc.clone())
453-
.doc_comment(Rc::clone(&doc_comment))
454-
.cpp_body(FuncCppBody::ManualCall("{{name}}".into())),
455-
))
456-
} else {
457-
None
458-
};
459-
let read_mut_func = if constness_filter.map_or(true, |c| c.is_mut()) {
460-
let cpp_name = fld.cpp_name(CppNameStyle::Declaration);
461-
Some(Func::new_desc(
462-
FuncDesc::new(
463-
FuncKind::FieldAccessor(self.clone(), fld.clone()),
464-
Constness::Mut,
465-
return_kind,
466-
format!("{cpp_name}Mut"),
467-
rust_module.clone(),
468-
[],
469-
fld_type_ref.as_ref().clone().with_inherent_constness(Constness::Mut),
470-
)
471-
.def_loc(def_loc.clone())
472-
.doc_comment(Rc::clone(&doc_comment))
473-
.cpp_body(FuncCppBody::ManualCall("{{name}}".into())),
474-
))
475-
} else {
476-
None
477-
};
478-
(read_const_func, read_mut_func)
417+
&Self::Clang { gen_env, .. } => {
418+
let accessor_generator = |fld: &Field<'tu, 'ge>| {
419+
let doc_comment = Rc::from(fld.doc_comment());
420+
let def_loc = fld.file_line_name().location;
421+
let rust_module = Rc::from(fld.rust_module());
422+
let mut fld_type_ref = fld.type_ref();
423+
let fld_type_kind = fld_type_ref.kind();
424+
if fld_type_kind
425+
.as_pointer()
426+
.map_or(false, |inner| inner.kind().as_primitive().is_some())
427+
&& !fld_type_kind.is_char_ptr_string(fld_type_ref.type_hint())
428+
{
429+
fld_type_ref.to_mut().set_type_hint(TypeRefTypeHint::PrimitivePtrAsRaw);
430+
} else if fld_type_kind.as_class().map_or(false, |cls| cls.kind().is_trait()) {
431+
fld_type_ref.to_mut().set_type_hint(TypeRefTypeHint::TraitClassConcrete);
432+
}
433+
let fld_type_kind = fld_type_ref.kind();
434+
let return_kind = ReturnKind::infallible(fld_type_kind.return_as_naked(fld_type_ref.type_hint()));
435+
let fld_const = fld.constness();
436+
let passed_by_ref = fld_type_kind.can_return_as_direct_reference();
437+
let fld_refname = fld.cpp_name(CppNameStyle::Reference);
438+
let rust_custom_leafname = gen_env.settings.property_rename.get(fld_refname.as_ref()).copied();
439+
let fld_declname = fld.cpp_name(CppNameStyle::Declaration);
440+
let (mut read_const_yield, mut read_mut_yield) = if fld_const.is_mut() && passed_by_ref {
441+
let read_const_func = if constness_filter.map_or(true, |c| c.is_const()) {
442+
Some(Func::new_desc(
443+
FuncDesc::new(
444+
FuncKind::FieldAccessor(self.clone(), fld.clone()),
445+
Constness::Const,
446+
return_kind,
447+
fld_declname.clone(),
448+
Rc::clone(&rust_module),
449+
[],
450+
fld_type_ref.as_ref().clone().with_inherent_constness(Constness::Const),
451+
)
452+
.def_loc(def_loc.clone())
453+
.doc_comment(Rc::clone(&doc_comment))
454+
.cpp_body(FuncCppBody::ManualCall("{{name}}".into()))
455+
.maybe_rust_custom_leafname(rust_custom_leafname),
456+
))
479457
} else {
480-
let read_const_func = if constness_filter.map_or(true, |c| c == fld_const) {
481-
Some(Func::new_desc(
482-
FuncDesc::new(
483-
FuncKind::FieldAccessor(self.clone(), fld.clone()),
484-
fld_const,
485-
return_kind,
486-
fld.cpp_name(CppNameStyle::Reference),
487-
rust_module.clone(),
488-
[],
489-
fld_type_ref.as_ref().clone(),
490-
)
491-
.def_loc(def_loc.clone())
492-
.doc_comment(Rc::clone(&doc_comment))
493-
.cpp_body(FuncCppBody::ManualCall("{{name}}".into())),
494-
))
495-
} else {
496-
None
497-
};
498-
(read_const_func, None)
458+
None
499459
};
500-
let mut write_yield = if constness_filter.map_or(true, |c| c.is_mut())
501-
&& !fld_type_ref.constness().is_const()
502-
&& !fld_type_kind.as_fixed_array().is_some()
503-
{
504-
let cpp_name = fld.cpp_name(CppNameStyle::Declaration);
505-
let (first_letter, rest) = cpp_name.capitalize_first_ascii_letter().expect("Empty fld_declname");
460+
let read_mut_func = if constness_filter.map_or(true, |c| c.is_mut()) {
506461
Some(Func::new_desc(
507462
FuncDesc::new(
508463
FuncKind::FieldAccessor(self.clone(), fld.clone()),
509464
Constness::Mut,
510-
ReturnKind::InfallibleNaked,
511-
format!("set{first_letter}{rest}"),
512-
rust_module.clone(),
513-
[Field::new_desc(FieldDesc {
514-
cpp_fullname: "val".into(),
515-
type_ref: fld_type_ref.as_ref().clone().with_inherent_constness(Constness::Const),
516-
default_value: fld.default_value().map(|v| v.into()),
517-
})],
518-
TypeRefDesc::void(),
465+
return_kind,
466+
format!("{fld_declname}Mut"),
467+
Rc::clone(&rust_module),
468+
[],
469+
fld_type_ref.as_ref().clone().with_inherent_constness(Constness::Mut),
519470
)
520-
.doc_comment(doc_comment)
521-
.def_loc(def_loc)
522-
.cpp_body(FuncCppBody::ManualCall("{{name}} = {{args}}".into())),
471+
.def_loc(def_loc.clone())
472+
.doc_comment(Rc::clone(&doc_comment))
473+
.cpp_body(FuncCppBody::ManualCall("{{name}}".into()))
474+
.maybe_rust_custom_leafname(rust_custom_leafname.map(|name| format!("{name}_mut"))),
523475
))
524476
} else {
525477
None
526478
};
527-
move || {
528-
read_const_yield
529-
.take()
530-
.or_else(|| read_mut_yield.take())
531-
.or_else(|| write_yield.take())
532-
}
479+
(read_const_func, read_mut_func)
480+
} else {
481+
let single_read_func = if constness_filter.map_or(true, |c| c == fld_const) {
482+
Some(Func::new_desc(
483+
FuncDesc::new(
484+
FuncKind::FieldAccessor(self.clone(), fld.clone()),
485+
fld_const,
486+
return_kind,
487+
fld_declname.clone(),
488+
Rc::clone(&rust_module),
489+
[],
490+
fld_type_ref.as_ref().clone(),
491+
)
492+
.def_loc(def_loc.clone())
493+
.doc_comment(Rc::clone(&doc_comment))
494+
.cpp_body(FuncCppBody::ManualCall("{{name}}".into()))
495+
.maybe_rust_custom_leafname(rust_custom_leafname),
496+
))
497+
} else {
498+
None
499+
};
500+
(single_read_func, None)
501+
};
502+
let mut write_yield = if constness_filter.map_or(true, |c| c.is_mut())
503+
&& !fld_type_ref.constness().is_const()
504+
&& !fld_type_kind.as_fixed_array().is_some()
505+
{
506+
let (first_letter, rest) = fld_declname.capitalize_first_ascii_letter().expect("Empty fld_declname");
507+
Some(Func::new_desc(
508+
FuncDesc::new(
509+
FuncKind::FieldAccessor(self.clone(), fld.clone()),
510+
Constness::Mut,
511+
ReturnKind::InfallibleNaked,
512+
format!("set{first_letter}{rest}"),
513+
Rc::clone(&rust_module),
514+
[Field::new_desc(FieldDesc {
515+
cpp_fullname: "val".into(),
516+
type_ref: fld_type_ref.as_ref().clone().with_inherent_constness(Constness::Const),
517+
default_value: fld.default_value().map(|v| v.into()),
518+
})],
519+
TypeRefDesc::void(),
520+
)
521+
.doc_comment(doc_comment)
522+
.def_loc(def_loc)
523+
.cpp_body(FuncCppBody::ManualCall("{{name}} = {{args}}".into()))
524+
.maybe_rust_custom_leafname(rust_custom_leafname.map(|name| format!("set_{name}"))),
525+
))
526+
} else {
527+
None
528+
};
529+
iter::from_fn(move || {
530+
read_const_yield
531+
.take()
532+
.or_else(|| read_mut_yield.take())
533+
.or_else(|| write_yield.take())
533534
})
534-
}));
535-
out
536-
}
537-
Self::Desc(_) => {
538-
vec![]
535+
};
536+
fields.flat_map(accessor_generator).collect()
539537
}
538+
Self::Desc(_) => vec![],
540539
}
541540
}
542541

binding-generator/src/func/desc.rs

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl<'tu, 'ge> FuncDesc<'tu, 'ge> {
3535
return_kind: ReturnKind,
3636
cpp_name: impl Into<Rc<str>>,
3737
rust_module: impl Into<Rc<str>>,
38-
arguments: impl IntoRc<[Field<'tu, 'ge>]>,
38+
arguments: impl Into<Rc<[Field<'tu, 'ge>]>>,
3939
return_type_ref: TypeRef<'tu, 'ge>,
4040
) -> Self {
4141
Self {
@@ -49,7 +49,7 @@ impl<'tu, 'ge> FuncDesc<'tu, 'ge> {
4949
doc_comment: "".into(),
5050
def_loc: DefinitionLocation::Generated,
5151
rust_generic_decls: Rc::new([]),
52-
arguments: arguments.into_rc(),
52+
arguments: arguments.into(),
5353
return_type_ref,
5454
cpp_body: FuncCppBody::Auto,
5555
rust_body: FuncRustBody::Auto,
@@ -63,39 +63,45 @@ impl<'tu, 'ge> FuncDesc<'tu, 'ge> {
6363
self
6464
}
6565

66+
#[inline]
67+
pub fn maybe_rust_custom_leafname(mut self, rust_custom_leafname: Option<impl Into<Rc<str>>>) -> Self {
68+
self.rust_custom_leafname = rust_custom_leafname.map(|name| name.into());
69+
self
70+
}
71+
6672
#[inline]
6773
pub fn doc_comment(mut self, doc_comment: impl Into<Rc<str>>) -> Self {
6874
self.doc_comment = doc_comment.into();
6975
self
7076
}
7177

7278
#[inline]
73-
pub fn cpp_body(mut self, cpp_body: FuncCppBody) -> Self {
74-
self.cpp_body = cpp_body;
79+
pub fn def_loc(mut self, def_loc: DefinitionLocation) -> Self {
80+
self.def_loc = def_loc;
7581
self
7682
}
7783

7884
#[inline]
79-
pub fn rust_body(mut self, rust_body: FuncRustBody) -> Self {
80-
self.rust_body = rust_body;
85+
pub fn rust_generic_decls(mut self, rust_generic_decls: impl Into<Rc<[(String, String)]>>) -> Self {
86+
self.rust_generic_decls = rust_generic_decls.into();
8187
self
8288
}
8389

8490
#[inline]
85-
pub fn def_loc(mut self, def_loc: DefinitionLocation) -> Self {
86-
self.def_loc = def_loc;
91+
pub fn cpp_body(mut self, cpp_body: FuncCppBody) -> Self {
92+
self.cpp_body = cpp_body;
8793
self
8894
}
8995

9096
#[inline]
91-
pub fn rust_extern_definition(mut self, rust_extern_definition: FuncRustExtern) -> Self {
92-
self.rust_extern_definition = rust_extern_definition;
97+
pub fn rust_body(mut self, rust_body: FuncRustBody) -> Self {
98+
self.rust_body = rust_body;
9399
self
94100
}
95101

96102
#[inline]
97-
pub fn rust_generic_decls(mut self, rust_generic_decls: impl IntoRc<[(String, String)]>) -> Self {
98-
self.rust_generic_decls = rust_generic_decls.into_rc();
103+
pub fn rust_extern_definition(mut self, rust_extern_definition: FuncRustExtern) -> Self {
104+
self.rust_extern_definition = rust_extern_definition;
99105
self
100106
}
101107

@@ -144,30 +150,3 @@ pub enum FuncRustBody {
144150
/// Specify manual call, use the automatic return handling
145151
ManualCallReturn(Cow<'static, str>),
146152
}
147-
148-
/// MSRV: remove this trait when MSRV allows and change `IntoRc<..>` in the `FuncDesc::new` to `Into<Rc<..>>`.
149-
/// Older rust versions don't allow passing `[]` in that case resulting in:
150-
/// ```text
151-
/// the trait `From<[_; 0]>` is not implemented for `Rc<[Field<'_, '_>]>
152-
/// ```
153-
pub trait IntoRc<Output: ?Sized> {
154-
fn into_rc(self) -> Rc<Output>;
155-
}
156-
157-
impl<const N: usize> IntoRc<[(String, String)]> for [(String, String); N] {
158-
fn into_rc(self) -> Rc<[(String, String)]> {
159-
self.to_vec().into()
160-
}
161-
}
162-
163-
impl<'tu, 'ge, const N: usize> IntoRc<[Field<'tu, 'ge>]> for [Field<'tu, 'ge>; N] {
164-
fn into_rc(self) -> Rc<[Field<'tu, 'ge>]> {
165-
self.to_vec().into()
166-
}
167-
}
168-
169-
impl<'tu, 'ge> IntoRc<[Field<'tu, 'ge>]> for Vec<Field<'tu, 'ge>> {
170-
fn into_rc(self) -> Rc<[Field<'tu, 'ge>]> {
171-
self.into()
172-
}
173-
}

binding-generator/src/settings.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub use implemented::{
2020
IMPLEMENTED_SYSTEM_CLASSES,
2121
};
2222
use once_cell::sync::Lazy;
23+
pub use property_rename::{property_rename_factory, PropertyRename};
2324

2425
use crate::type_ref::TypeRef;
2526

@@ -37,6 +38,7 @@ mod func_specialize;
3738
mod func_unsafe;
3839
mod generator_module_tweaks;
3940
mod implemented;
41+
mod property_rename;
4042

4143
pub type TypeRefFactory = fn() -> TypeRef<'static, 'static>;
4244

@@ -46,7 +48,8 @@ pub struct Settings {
4648
pub func_inject: FuncInject,
4749
pub func_rename: FuncRename,
4850
pub func_specialize: FuncSpecialize,
49-
pub generator_module_tweaks: ModuleTweak<'static>,
51+
pub generator_module_tweaks: ModuleTweak,
52+
pub property_rename: PropertyRename,
5053
}
5154

5255
impl Settings {
@@ -56,6 +59,7 @@ impl Settings {
5659
func_rename: HashMap::new(),
5760
func_specialize: HashMap::new(),
5861
generator_module_tweaks: ModuleTweak::empty(),
62+
property_rename: HashMap::new(),
5963
}
6064
}
6165

@@ -65,6 +69,7 @@ impl Settings {
6569
func_rename: func_rename_factory(module),
6670
func_specialize: func_specialize_factory(module),
6771
generator_module_tweaks: generator_module_tweaks_factory(module),
72+
property_rename: property_rename_factory(module),
6873
}
6974
}
7075
}

binding-generator/src/settings/func_rename.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,7 @@ fn objdetect_factory() -> HashMap<&'static str, &'static str> {
634634
("cv_HOGDescriptor_detectMultiScale_const_const__InputArrayR_vectorLRectGR_vectorLdoubleGR_double_Size_Size_double_double_bool", "+_weights"),
635635
("cv_HOGDescriptor_detect_const_const_MatR_vectorLPointGR_vectorLdoubleGR_double_Size_Size_const_vectorLPointGR", "+_weights"), // 3.2 3.4
636636
("cv_HOGDescriptor_detect_const_const__InputArrayR_vectorLPointGR_vectorLdoubleGR_double_Size_Size_const_vectorLPointGR", "+_weights"), // 4.x
637+
("cv_HOGDescriptor_setSVMDetector_const__InputArrayR", "+_input_array"),
637638
("cv_aruco_getPredefinedDictionary_int", "+_i32"),
638639
("cv_groupRectangles_vectorLRectGR_int_double_vectorLintGX_vectorLdoubleGX", "+_levelweights"),
639640
("cv_groupRectangles_vectorLRectGR_vectorLintGR_int_double", "+_weights"),

0 commit comments

Comments
 (0)