Skip to main content

opencv_binding_generator/
smart_ptr.rs

1use 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}