message: implement safe dereferencing Ptr<_> in rust
diff: @@ -2991,6 +2991,41 @@ class SmartPtrTypeInfo(TypeInfo):
  }
  """),
  +
  + "rust_deref": template("""
  + pub struct ${rust_deref_guard}<'a> {
  + guarded: &'a ${rust_local},
  + inner: std::mem::ManuallyDrop<${inner_rust_full}>,
  + }
  +
  + impl<'a> std::ops::Deref for ${rust_deref_guard}<'a> {
  + type Target = ${inner_rust_full};
  +
  + fn deref(&self) -> &Self::Target {
  + self.inner.deref()
  + }
  + }
  +
  + impl<'a> std::ops::DerefMut for ${rust_deref_guard}<'a> {
  + fn deref_mut(&mut self) -> &mut Self::Target {
  + self.inner.deref_mut()
  + }
  + }
  +
  + impl ${rust_local} {
  + pub fn deref_mut<'a>(&'a mut self) -> ${rust_deref_guard}<'a> {
  + let me = self.ptr;
  + let inner_ptr = cpp!(unsafe [me as "cv::Ptr<${inner_cpp_type}>*"] -> ${rust_extern} as "${cpp_extern}" {
  + return me->get();
  + });
  + let inner = ${inner_rust_full} { ptr: inner_ptr };
  + ${rust_deref_guard} {
  + guarded: self,
  + inner: std::mem::ManuallyDrop::new(inner),
  + }
  + }
  + }
  + """),
  }
  def __init__(self, gen, typeid, inner):
  @@ -3014,7 +3049,8 @@ class SmartPtrTypeInfo(TypeInfo):
  def gen_wrappers(self):
  def write_rust(f):
  f.write(SmartPtrTypeInfo.TEMPLATES["rust"].substitute(self.__dict__))
  - if not isinstance(self.inner, PrimitiveTypeInfo) and self.inner.ci.is_trait:
  + if not isinstance(self.inner, PrimitiveTypeInfo):
  + if self.inner.ci.is_trait:
  bases = self.gen.all_bases(self.inner.ci.name).union({self.inner.typeid})
  for base in sorted(bases):
  cibase = self.gen.get_type_info(base)
  @@ -3024,6 +3060,13 @@ class SmartPtrTypeInfo(TypeInfo):
  "base_rust_full": cibase.rust_trait_full(),
  "base_cpp_type": cibase.cpptype,
  })))
  + else:
  + rust_deref_guard = "{}Guard".format(self.rust_local)
  + f.write(SmartPtrTypeInfo.TEMPLATES["rust_deref"].substitute(combine_dicts(self.__dict__ , {
  + "inner_rust_full": self.inner.rust_full,
  + "inner_cpp_type": self.inner.cpptype,
  + "rust_deref_guard": rust_deref_guard,
  + })))
  write_exc("{}/{}-{}.type.rs".format(self.gen.rust_dir, self.rust_module(), self.rust_safe_id), write_rust)
  