Rework rust_extern
MODIFY
binding-generator/src/function.rs
binding-generator/src/function.rs
@@ -3,7 +3,7 @@ use std::fmt;
use clang::{Entity, EntityKind, EntityVisitResult, Type};
-use crate::type_ref::{ConstnessOverride, CppNameStyle, NameStyle};
+use crate::type_ref::{CppNameStyle, ExternDir, NameStyle};
use crate::{Element, Field, GeneratorEnv, IteratorExt, TypeRef};
#[derive(Clone)]
@@ -50,13 +50,13 @@ impl<'tu, 'ge> Function<'tu, 'ge> {
let args = self
.arguments()
.into_iter()
- .map(|a| a.type_ref().rust_extern(ConstnessOverride::No).into_owned())
+ .map(|a| a.type_ref().rust_extern(ExternDir::Pure).into_owned())
.join(", ");
let ret = self.return_type();
format!(
r#"Option<unsafe extern "C" fn({args}) -> {ret}>"#,
args = args,
- ret = ret.rust_extern(ConstnessOverride::No)
+ ret = ret.rust_extern(ExternDir::Pure)
)
.into()
}
@@ -103,13 +103,13 @@ impl Element for Function<'_, '_> {
let args = self
.rust_arguments()
.into_iter()
- .map(|a| a.type_ref().rust_extern(ConstnessOverride::No).into_owned())
+ .map(|a| a.type_ref().rust_extern(ExternDir::Pure).into_owned())
.join(", ");
format!(
"Option{fish}<Box{fish}<dyn FnMut({args}) -> {ret} + Send + Sync + 'static>>",
fish = style.turbo_fish_style().rust_qual(),
args = args,
- ret = ret.rust_extern(ConstnessOverride::No),
+ ret = ret.rust_extern(ExternDir::Pure),
)
.into()
} else {

MODIFY
binding-generator/src/type_ref.rs
binding-generator/src/type_ref.rs
@@ -53,6 +53,13 @@ pub enum Dir<T> {
Out(T),
}
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum ExternDir {
+ Pure, // used for inner type (e.g. for Point*) and for callbacks
+ ToCpp(ConstnessOverride),
+ FromCpp,
+}
+
#[derive(Clone, Debug)]
pub enum Kind<'tu, 'ge> {
/// (rust name, cpp name)
@@ -840,24 +847,23 @@ impl<'tu, 'ge> TypeRef<'tu, 'ge> {
Lifetime::explicit().into_iter().take(self.rust_lifetime_count())
}
- pub fn rust_extern(&self, constness: ConstnessOverride) -> Cow<str> {
- let constness = constness.with(self.constness());
+ pub fn rust_extern(&self, dir: ExternDir) -> Cow<str> {
+ let constness = match dir {
+ ExternDir::Pure => self.constness(),
+ ExternDir::ToCpp(constness) => constness.with(self.constness()),
+ ExternDir::FromCpp => Constness::Mut,
+ };
#[allow(clippy::never_loop)] // fixme use named block when MSRV is 1.65
'typ: loop {
- if let Some(dir) = self.as_string() {
- match dir {
- Dir::In(_) => {
- break 'typ if constness.is_const() {
- "*const c_char".into()
- } else {
- "*mut c_char".into()
+ if let Some(arg_dir) = self.as_string() {
+ break 'typ match dir {
+ ExternDir::ToCpp(_) | ExternDir::Pure => match arg_dir {
+ Dir::In(_) => format!("*{}c_char", constness.rust_qual(true)).into(),
+ Dir::Out(_) => "*mut *mut c_void".into(),
+ },
+ ExternDir::FromCpp => "*mut c_void".into(),
};
}
- Dir::Out(_) => {
- break 'typ "*mut *mut c_void".into();
- }
- }
- }
if self.is_extern_by_ptr() {
break 'typ if constness.is_const() {
"*const c_void"
@@ -874,7 +880,7 @@ impl<'tu, 'ge> TypeRef<'tu, 'ge> {
} else if self.as_string().is_some() {
out += "c_char";
} else {
- out += inner.rust_extern(ConstnessOverride::force(constness)).as_ref()
+ out += inner.rust_extern(ExternDir::Pure).as_ref()
}
break 'typ out.into();
}
@@ -882,7 +888,7 @@ impl<'tu, 'ge> TypeRef<'tu, 'ge> {
break 'typ format!(
"*{cnst}[{typ}; {len}]",
cnst = self.constness().rust_qual(true),
- typ = elem.rust_extern(ConstnessOverride::force(constness)),
+ typ = elem.rust_extern(ExternDir::Pure),
len = len,
)
.into();
@@ -893,13 +899,18 @@ impl<'tu, 'ge> TypeRef<'tu, 'ge> {
// argv is treated as array of output arguments and it doesn't seem to be meant this way
format!("*{cnst}c_char", cnst = elem.clang_constness().rust_qual(true)).into()
} else {
- elem.rust_extern(ConstnessOverride::force(constness))
+ elem.rust_extern(ExternDir::Pure)
};
- break 'typ format!("*{cnst}{typ}", cnst = self.constness().rust_qual(true), typ = typ,).into();
+ break 'typ format!("*{cnst}{typ}", cnst = self.constness().rust_qual(true), typ = typ).into();
}
if let Some(func) = self.as_function() {
break 'typ func.rust_extern().into_owned().into();
}
+ if self.as_simple_class().is_some() {
+ if matches!(dir, ExternDir::ToCpp(_)) {
+ break 'typ format!("*const {}", self.rust_name(NameStyle::ref_())).into();
+ }
+ }
break 'typ self.rust_name(NameStyle::ref_());
}
}
@@ -1153,7 +1164,7 @@ impl fmt::Debug for TypeRef<'_, '_> {
let mut dbg = f.debug_struct("TypeRef");
dbg.field("rust_safe_id", &self.rust_safe_id(true))
.field("rust_full", &self.rust_name(NameStyle::ref_()))
- .field("rust_extern", &self.rust_extern(ConstnessOverride::No))
+ .field("rust_extern", &self.rust_extern(ExternDir::ToCpp(ConstnessOverride::No)))
.field("cpp_safe_id", &self.cpp_safe_id())
.field("cpp_full", &self.cpp_name(CppNameStyle::Reference))
.field("cpp_extern", &self.cpp_extern())

MODIFY
binding-generator/src/writer/rust_native/abstract_ref_wrapper.rs
binding-generator/src/writer/rust_native/abstract_ref_wrapper.rs
use maplit::hashmap;
use once_cell::sync::Lazy;
-use crate::type_ref::{Constness, ConstnessOverride, NameStyle};
+use crate::type_ref::{Constness, ConstnessOverride, ExternDir, NameStyle};
use crate::{AbstractRefWrapper, CompiledInterpolation, StrExt};
use super::RustNativeGeneratedElement;
@@ -26,8 +26,8 @@ impl RustNativeGeneratedElement for AbstractRefWrapper<'_, '_> {
"rust_full" => cls.rust_trait_name(NameStyle::ref_(), Constness::Mut),
"rust_const_full" => cls.rust_trait_name(NameStyle::ref_(), Constness::Const),
"rust_local" => type_ref.rust_name(NameStyle::decl()),
- "rust_extern_mut" => type_ref.rust_extern(ConstnessOverride::Mut),
- "rust_extern_const" => type_ref.rust_extern(ConstnessOverride::Const),
+ "rust_extern_mut" => type_ref.rust_extern(ExternDir::ToCpp(ConstnessOverride::Mut)),
+ "rust_extern_const" => type_ref.rust_extern(ExternDir::ToCpp(ConstnessOverride::Const)),
})
}
}

MODIFY
binding-generator/src/writer/rust_native/class.rs
binding-generator/src/writer/rust_native/class.rs
@@ -4,7 +4,7 @@ use maplit::hashmap;
use once_cell::sync::Lazy;
use crate::class::Kind;
-use crate::type_ref::{Constness, ConstnessOverride, CppNameStyle, FishStyle, NameStyle};
+use crate::type_ref::{Constness, ConstnessOverride, CppNameStyle, ExternDir, FishStyle, NameStyle};
use crate::writer::rust_native::func_desc::{ClassDesc, CppFuncDesc, FuncDescCppCall, FuncDescKind};
use crate::{get_debug, Class, CompiledInterpolation, Element, Func, FunctionTypeHint, IteratorExt, NamePool, StrExt, TypeRef};
@@ -127,8 +127,8 @@ fn gen_rust_class(c: &Class, opencv_version: &str) -> String {
"rust_trait_local" => c.rust_trait_name(NameStyle::decl(), Constness::Mut),
"rust_trait_local_const" => c.rust_trait_name(NameStyle::decl(), Constness::Const),
"rust_local" => type_ref.rust_name(NameStyle::decl()),
- "rust_extern_const" => type_ref.rust_extern(ConstnessOverride::Const),
- "rust_extern_mut" => type_ref.rust_extern(ConstnessOverride::Mut),
+ "rust_extern_const" => type_ref.rust_extern(ExternDir::ToCpp(ConstnessOverride::Const)),
+ "rust_extern_mut" => type_ref.rust_extern(ExternDir::ToCpp(ConstnessOverride::Mut)),
"trait_bases_const" => trait_bases_const.into(),
"trait_bases_mut" => trait_bases_mut.into(),
"trait_const_methods" => trait_const_methods.into(),
@@ -204,8 +204,8 @@ fn gen_rust_class(c: &Class, opencv_version: &str) -> String {
"base_const_rust_full" => base.rust_trait_name(NameStyle::ref_(), Constness::Const),
"rust_local" => type_ref.rust_name(NameStyle::decl()),
"base_rust_local" => base_type_ref.rust_name(NameStyle::decl()),
- "base_rust_extern_const" => base_type_ref.rust_extern(ConstnessOverride::Const),
- "base_rust_extern_mut" => base_type_ref.rust_extern(ConstnessOverride::Mut),
+ "base_rust_extern_const" => base_type_ref.rust_extern(ExternDir::ToCpp(ConstnessOverride::Const)),
+ "base_rust_extern_mut" => base_type_ref.rust_extern(ExternDir::ToCpp(ConstnessOverride::Mut)),
})
})
.collect::<Vec<_>>();
@@ -294,8 +294,8 @@ fn gen_rust_class(c: &Class, opencv_version: &str) -> String {
"debug" => get_debug(c).into(),
"rust_local" => rust_local.clone(),
"rust_full" => c.rust_name(NameStyle::ref_()),
- "rust_extern_const" => type_ref.rust_extern(ConstnessOverride::Const),
- "rust_extern_mut" => type_ref.rust_extern(ConstnessOverride::Mut),
+ "rust_extern_const" => type_ref.rust_extern(ExternDir::ToCpp(ConstnessOverride::Const)),
+ "rust_extern_mut" => type_ref.rust_extern(ExternDir::ToCpp(ConstnessOverride::Mut)),
"fields" => fields.join("").into(),
"bases" => bases.join("").into(),
"impl" => IMPL_TPL.interpolate(&hashmap! {

MODIFY
binding-generator/src/writer/rust_native/func.rs
binding-generator/src/writer/rust_native/func.rs
@@ -5,7 +5,7 @@ use maplit::hashmap;
use once_cell::sync::Lazy;
use crate::func::Kind;
-use crate::type_ref::{ConstnessOverride, CppNameStyle, Dir, FishStyle, NameStyle, StrEnc, StrType};
+use crate::type_ref::{ConstnessOverride, CppNameStyle, Dir, ExternDir, FishStyle, NameStyle, StrEnc, StrType};
use crate::writer::rust_native::func_desc::{pre_post_arg_handle, CppFuncDesc, FuncDescCppCall, FuncDescKind};
use crate::{get_debug, settings, CompiledInterpolation, Element, Field, Func, StrExt, TypeRef};
@@ -337,7 +337,7 @@ impl RustNativeGeneratedElement for Func<'_, '_> {
let is_infallible = self.is_infallible();
let return_type = self.return_type();
let return_wrapper_type = if is_infallible {
- return_type.rust_extern_return()
+ return_type.rust_extern(ExternDir::FromCpp)
} else {
return_type.rust_extern_return_fallible()
};

MODIFY
binding-generator/src/writer/rust_native/smart_ptr.rs
binding-generator/src/writer/rust_native/smart_ptr.rs
@@ -2,7 +2,7 @@ use maplit::hashmap;
use once_cell::sync::Lazy;
use std::borrow::Cow;
-use crate::type_ref::{Constness, ConstnessOverride, CppNameStyle, NameStyle};
+use crate::type_ref::{Constness, ConstnessOverride, CppNameStyle, ExternDir, NameStyle};
use crate::writer::rust_native::func_desc::{ClassDesc, CppFuncDesc, FuncDescCppCall, FuncDescKind};
use crate::{type_ref, CompiledInterpolation, Element, EntityElement, FunctionTypeHint, SmartPtr, StrExt, TypeRef};
@@ -32,8 +32,8 @@ impl RustNativeGeneratedElement for SmartPtr<'_, '_> {
let mut inter_vars = hashmap! {
"rust_localalias" => self.rust_localalias(),
"rust_full" => self.rust_name(NameStyle::ref_()),
- "rust_extern_const" => type_ref.rust_extern(ConstnessOverride::Const),
- "rust_extern_mut" => type_ref.rust_extern(ConstnessOverride::Mut),
+ "rust_extern_const" => type_ref.rust_extern(ExternDir::ToCpp(ConstnessOverride::Const)),
+ "rust_extern_mut" => type_ref.rust_extern(ExternDir::ToCpp(ConstnessOverride::Mut)),
"inner_rust_full" => pointee_type.rust_name(NameStyle::ref_()),
};

MODIFY
binding-generator/src/writer/rust_native/type_ref.rs
binding-generator/src/writer/rust_native/type_ref.rs
@@ -2,7 +2,7 @@ use crate::{Field, IteratorExt};
use std::borrow::Cow;
use crate::type_ref::{
- Constness, ConstnessOverride, CppNameStyle, Dir, FishStyle, NameStyle, Signedness, StrEnc, StrType, TypeRef,
+ Constness, ConstnessOverride, CppNameStyle, Dir, ExternDir, FishStyle, NameStyle, Signedness, StrEnc, StrType, TypeRef,
};
pub trait TypeRefExt {
@@ -19,7 +19,6 @@ pub trait TypeRefExt {
fn rust_arg_forward(&self, name: &str) -> String;
fn rust_arg_post_call(&self, name: &str, _is_function_infallible: bool) -> String;
fn rust_return(&self, turbo_fish_style: FishStyle, is_static_func: bool) -> Cow<str>;
- fn rust_extern_return(&self) -> Cow<str>;
fn rust_extern_return_fallible(&self) -> Cow<str>;
fn cpp_self_func_decl(&self, method_constness: Constness) -> String;
@@ -92,11 +91,11 @@ impl<'tu, 'ge> TypeRefExt for TypeRef<'tu, 'ge> {
}
fn rust_extern_arg_func_decl(&self, name: &str, constness: ConstnessOverride) -> String {
- let mut typ = self.rust_extern(constness);
- if self.as_simple_class().is_some() {
- *typ.to_mut() = format!("*const {}", typ)
- }
- format!("{name}: {typ}", name = name, typ = typ)
+ format!(
+ "{name}: {typ}",
+ name = name,
+ typ = self.rust_extern(ExternDir::ToCpp(constness))
+ )
}
fn rust_arg_pre_call(&self, name: &str, is_function_infallible: bool) -> String {
@@ -147,10 +146,10 @@ impl<'tu, 'ge> TypeRefExt for TypeRef<'tu, 'ge> {
"callback_arg!({name}_trampoline({tramp_args}) -> {tramp_ret} => {tramp_userdata_arg} in callbacks => {name}({fw_args}) -> {fw_ret})",
name=name,
tramp_args=tramp_args,
- tramp_ret=ret.rust_extern(ConstnessOverride::No),
+ tramp_ret=ret.rust_extern(ExternDir::FromCpp),
tramp_userdata_arg=userdata_name,
fw_args=fw_args,
- fw_ret=ret.rust_extern(ConstnessOverride::No),
+ fw_ret=ret.rust_extern(ExternDir::FromCpp),
);
}
}
@@ -328,19 +327,11 @@ impl<'tu, 'ge> TypeRefExt for TypeRef<'tu, 'ge> {
}
}
- fn rust_extern_return(&self) -> Cow<str> {
- if self.as_string().is_some() {
- "*mut c_void".into()
- } else {
- self.rust_extern(ConstnessOverride::Mut)
- }
- }
-
fn rust_extern_return_fallible(&self) -> Cow<str> {
if self.is_void() {
"Result_void".into()
} else {
- format!("Result<{ext}>", ext = self.rust_extern_return()).into()
+ format!("Result<{ext}>", ext = self.rust_extern(ExternDir::FromCpp)).into()
}
}

MODIFY
binding-generator/src/writer/rust_native/vector.rs
binding-generator/src/writer/rust_native/vector.rs
use maplit::hashmap;
use once_cell::sync::Lazy;
-use crate::type_ref::{Constness, ConstnessOverride, CppNameStyle, NameStyle};
+use crate::type_ref::{Constness, ConstnessOverride, CppNameStyle, ExternDir, NameStyle};
use crate::writer::rust_native::func_desc::{ClassDesc, CppFuncDesc, FuncDescCppCall, FuncDescKind};
use crate::{settings, CompiledInterpolation, Element, FunctionTypeHint, StrExt, TypeRef, Vector};
@@ -37,10 +37,10 @@ impl RustNativeGeneratedElement for Vector<'_, '_> {
let mut inter_vars = hashmap! {
"rust_localalias" => self.rust_localalias(),
"rust_full" => self.rust_name(NameStyle::ref_()),
- "rust_extern_const" => vec_type.rust_extern(ConstnessOverride::Const),
- "rust_extern_mut" => vec_type.rust_extern(ConstnessOverride::Mut),
+ "rust_extern_const" => vec_type.rust_extern(ExternDir::ToCpp(ConstnessOverride::Const)),
+ "rust_extern_mut" => vec_type.rust_extern(ExternDir::ToCpp(ConstnessOverride::Mut)),
"inner_rust_full" => element_type.rust_name(NameStyle::ref_()),
- "inner_rust_extern_return" => element_type.rust_extern_return(),
+ "inner_rust_extern_return" => element_type.rust_extern(ExternDir::FromCpp),
};
if settings::PREVENT_VECTOR_TYPEDEF_GENERATION.contains(element_type.cpp_name(CppNameStyle::Reference).as_ref()) {

Rework rust_extern