opencv_binding_generator/
smart_ptr.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use std::borrow::Cow;
use std::borrow::Cow::{Borrowed, Owned};
use std::fmt;
use std::rc::Rc;

use clang::Entity;

pub use desc::SmartPtrDesc;

use crate::element::ExcludeKind;
use crate::type_ref::{Constness, CppNameStyle, TypeRef, TypeRefDesc, TypeRefKind};
use crate::{DefaultElement, Element, GeneratedType, GeneratorEnv, StrExt};

mod desc;

#[derive(Clone)]
pub enum SmartPtr<'tu, 'ge> {
	Clang {
		entity: Entity<'tu>,
		gen_env: &'ge GeneratorEnv<'tu>,
	},
	Desc(Rc<SmartPtrDesc<'tu, 'ge>>),
}

impl<'tu, 'ge> SmartPtr<'tu, 'ge> {
	pub fn new(entity: Entity<'tu>, gen_env: &'ge GeneratorEnv<'tu>) -> Self {
		Self::Clang { entity, gen_env }
	}

	pub fn new_desc(desc: SmartPtrDesc<'tu, 'ge>) -> Self {
		Self::Desc(Rc::new(desc))
	}

	pub fn type_ref(&self) -> TypeRef<'tu, 'ge> {
		match self {
			&Self::Clang { entity, gen_env, .. } => TypeRef::new(entity.get_type().expect("Can't get smart pointer type"), gen_env),
			Self::Desc(_) => TypeRef::new_desc(TypeRefDesc::new(TypeRefKind::SmartPtr(self.clone()), Constness::Mut)),
		}
	}

	pub fn pointee(&self) -> Cow<TypeRef<'tu, 'ge>> {
		match self {
			&Self::Clang { .. } => Owned(
				self
					.type_ref()
					.template_specialization_args()
					.iter()
					.find_map(|arg| arg.as_typename())
					.cloned()
					.expect("Smart pointer template argument list is empty"),
			),
			Self::Desc(desc) => Borrowed(&desc.pointee_type_ref),
		}
	}

	pub fn generated_types(&self) -> Vec<GeneratedType<'tu, 'ge>> {
		let pointee = self.pointee();
		let pointee_kind = pointee.kind();
		let mut out = if let Some(cls) = pointee_kind.as_class() {
			cls.all_family()
				.into_iter()
				.map(|desc| GeneratedType::SmartPtr(SmartPtr::new_desc(SmartPtrDesc::new(TypeRef::new_class(desc)))))
				.collect()
		} else {
			vec![]
		};
		if let Some(typedef) = pointee_kind.as_typedef() {
			out.extend(typedef.generated_types());
		}
		out
	}
}

impl Element for SmartPtr<'_, '_> {
	fn exclude_kind(&self) -> ExcludeKind {
		DefaultElement::exclude_kind(self).with_exclude_kind(|| self.pointee().exclude_kind())
	}

	fn is_system(&self) -> bool {
		match self {
			&Self::Clang { entity, .. } => DefaultElement::is_system(entity),
			Self::Desc(_) => false,
		}
	}

	fn is_public(&self) -> bool {
		match self {
			&Self::Clang { entity, .. } => DefaultElement::is_public(entity),
			Self::Desc(_) => true,
		}
	}

	fn doc_comment(&self) -> Cow<str> {
		"".into()
	}

	fn cpp_namespace(&self) -> Cow<str> {
		"cv".into()
	}

	fn cpp_name(&self, style: CppNameStyle) -> Cow<str> {
		"cv::Ptr".cpp_name_from_fullname(style).into()
	}
}

impl PartialEq for SmartPtr<'_, '_> {
	fn eq(&self, other: &Self) -> bool {
		self.pointee() == other.pointee()
	}
}

impl fmt::Debug for SmartPtr<'_, '_> {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		let mut debug_struct = f.debug_struct(match self {
			Self::Clang { .. } => "SmartPtr::Clang",
			Self::Desc(_) => "SmartPtr::Desc",
		});
		self
			.update_debug_struct(&mut debug_struct)
			.field("pointee", &self.pointee())
			.finish()
	}
}