opencv_binding_generator/
smart_ptr.rs1use std::borrow::Cow;
2use std::borrow::Cow::{Borrowed, Owned};
3use std::fmt;
4use std::rc::Rc;
5
6use clang::Entity;
7pub use desc::SmartPtrDesc;
8
9use crate::element::ExcludeKind;
10use crate::type_ref::{Constness, CppNameStyle, TypeRef, TypeRefDesc, TypeRefKind};
11use crate::{DefaultElement, Element, GeneratedType, GeneratorEnv, StrExt};
12
13mod desc;
14
15#[derive(Clone)]
16pub enum SmartPtr<'tu, 'ge> {
17 Clang {
18 entity: Entity<'tu>,
19 gen_env: &'ge GeneratorEnv<'tu>,
20 },
21 Desc(Rc<SmartPtrDesc<'tu, 'ge>>),
22}
23
24impl<'tu, 'ge> SmartPtr<'tu, 'ge> {
25 pub fn new(entity: Entity<'tu>, gen_env: &'ge GeneratorEnv<'tu>) -> Self {
26 Self::Clang { entity, gen_env }
27 }
28
29 pub fn new_desc(desc: SmartPtrDesc<'tu, 'ge>) -> Self {
30 Self::Desc(Rc::new(desc))
31 }
32
33 pub fn type_ref(&self) -> TypeRef<'tu, 'ge> {
34 match self {
35 &Self::Clang { entity, gen_env, .. } => TypeRef::new(entity.get_type().expect("Can't get smart pointer type"), gen_env),
36 Self::Desc(_) => TypeRef::new_desc(TypeRefDesc::new(TypeRefKind::SmartPtr(self.clone()), Constness::Mut)),
37 }
38 }
39
40 pub fn pointee(&self) -> Cow<'_, TypeRef<'tu, 'ge>> {
41 match self {
42 &Self::Clang { .. } => Owned(
43 self
44 .type_ref()
45 .template_specialization_args()
46 .iter()
47 .find_map(|arg| arg.as_typename())
48 .cloned()
49 .expect("Smart pointer template argument list is empty"),
50 ),
51 Self::Desc(desc) => Borrowed(&desc.pointee_type_ref),
52 }
53 }
54
55 pub fn generated_types(&self) -> Vec<GeneratedType<'tu, 'ge>> {
56 let pointee = self.pointee();
57 let pointee_kind = pointee.kind();
58 let mut out = if let Some(cls) = pointee_kind.as_class() {
59 cls.all_family()
60 .into_iter()
61 .map(|desc| GeneratedType::SmartPtr(SmartPtr::new_desc(SmartPtrDesc::new(TypeRef::new_class(desc)))))
62 .collect()
63 } else {
64 vec![]
65 };
66 if let Some(typedef) = pointee_kind.as_typedef() {
67 out.extend(typedef.generated_types());
68 }
69 out
70 }
71}
72
73impl Element for SmartPtr<'_, '_> {
74 fn exclude_kind(&self) -> ExcludeKind {
75 DefaultElement::exclude_kind(self).with_exclude_kind(|| self.pointee().exclude_kind())
76 }
77
78 fn is_system(&self) -> bool {
79 match self {
80 &Self::Clang { entity, .. } => DefaultElement::is_system(entity),
81 Self::Desc(_) => false,
82 }
83 }
84
85 fn is_public(&self) -> bool {
86 match self {
87 &Self::Clang { entity, .. } => DefaultElement::is_public(entity),
88 Self::Desc(_) => true,
89 }
90 }
91
92 fn doc_comment(&self) -> Cow<'_, str> {
93 "".into()
94 }
95
96 fn cpp_namespace(&self) -> Cow<'_, str> {
97 "cv".into()
98 }
99
100 fn cpp_name(&self, style: CppNameStyle) -> Cow<'_, str> {
101 "cv::Ptr".cpp_name_from_fullname(style).into()
102 }
103}
104
105impl PartialEq for SmartPtr<'_, '_> {
106 fn eq(&self, other: &Self) -> bool {
107 self.pointee() == other.pointee()
108 }
109}
110
111impl fmt::Debug for SmartPtr<'_, '_> {
112 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113 let mut debug_struct = f.debug_struct(match self {
114 Self::Clang { .. } => "SmartPtr::Clang",
115 Self::Desc(_) => "SmartPtr::Desc",
116 });
117 self
118 .update_debug_struct(&mut debug_struct)
119 .field("pointee", &self.pointee())
120 .finish()
121 }
122}