gstreamer/
pad_template.rs1use std::ffi::CStr;
4
5use glib::{prelude::*, translate::*};
6
7use crate::{ffi, Caps, PadDirection, PadPresence, PadTemplate, StaticPadTemplate};
8
9impl PadTemplate {
10 #[doc(alias = "gst_pad_template_new_from_static_pad_template_with_gtype")]
11 pub fn from_static_pad_template_with_gtype(
12 pad_template: &StaticPadTemplate,
13 pad_type: glib::types::Type,
14 ) -> Result<PadTemplate, glib::BoolError> {
15 skip_assert_initialized!();
16 unsafe {
17 Option::<_>::from_glib_none(
18 ffi::gst_pad_template_new_from_static_pad_template_with_gtype(
19 mut_override(pad_template.to_glib_none().0),
20 pad_type.into_glib(),
21 ),
22 )
23 .ok_or_else(|| glib::bool_error!("Failed to create PadTemplate"))
24 }
25 }
26
27 #[doc(alias = "gst_pad_template_get_caps")]
28 #[doc(alias = "get_caps")]
29 pub fn caps(&self) -> &Caps {
30 unsafe {
31 let templ = &*(self.as_ptr() as *const ffi::GstPadTemplate);
32 &*(&templ.caps as *const *mut ffi::GstCaps as *const Caps)
33 }
34 }
35
36 #[cfg(feature = "v1_18")]
37 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
38 #[doc(alias = "gst_pad_template_get_documentation_caps")]
39 #[doc(alias = "get_documentation_caps")]
40 pub fn documentation_caps(&self) -> &Caps {
41 unsafe {
42 let templ = &*(self.as_ptr() as *const ffi::GstPadTemplate);
43 if !templ.ABI.abi.documentation_caps.is_null() {
44 &*(&templ.ABI.abi.documentation_caps as *const *mut ffi::GstCaps as *const Caps)
45 } else {
46 &*(&templ.caps as *const *mut ffi::GstCaps as *const Caps)
47 }
48 }
49 }
50
51 pub fn direction(&self) -> PadDirection {
52 unsafe {
53 let templ = &*(self.as_ptr() as *const ffi::GstPadTemplate);
54 from_glib(templ.direction)
55 }
56 }
57
58 pub fn gtype(&self) -> glib::types::Type {
59 unsafe {
60 let templ = &*(self.as_ptr() as *const ffi::GstPadTemplate);
61 from_glib(templ.ABI.abi.gtype)
62 }
63 }
64
65 #[doc(alias = "name-template")]
66 pub fn name_template(&self) -> &str {
67 unsafe {
68 let templ = &*(self.as_ptr() as *const ffi::GstPadTemplate);
69 CStr::from_ptr(templ.name_template).to_str().unwrap()
70 }
71 }
72
73 pub fn presence(&self) -> PadPresence {
74 unsafe {
75 let templ = &*(self.as_ptr() as *const ffi::GstPadTemplate);
76 from_glib(templ.presence)
77 }
78 }
79
80 pub fn builder<'a>(
81 name_template: &'a str,
82 direction: PadDirection,
83 presence: PadPresence,
84 caps: &'a Caps,
85 ) -> PadTemplateBuilder<'a> {
86 skip_assert_initialized!();
87
88 PadTemplateBuilder {
89 name_template,
90 direction,
91 presence,
92 caps,
93 gtype: None,
94 #[cfg(feature = "v1_18")]
95 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
96 documentation_caps: None,
97 }
98 }
99}
100
101#[must_use = "The builder must be built to be used"]
102#[derive(Debug)]
103pub struct PadTemplateBuilder<'a> {
104 name_template: &'a str,
105 direction: PadDirection,
106 presence: PadPresence,
107 caps: &'a Caps,
108 gtype: Option<glib::Type>,
109 #[cfg(feature = "v1_18")]
110 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
111 documentation_caps: Option<&'a Caps>,
112}
113
114#[allow(clippy::needless_lifetimes)]
115impl<'a> PadTemplateBuilder<'a> {
116 pub fn gtype(self, gtype: glib::Type) -> Self {
117 PadTemplateBuilder {
118 gtype: Some(gtype),
119 ..self
120 }
121 }
122
123 pub fn gtype_if(self, gtype: glib::Type, predicate: bool) -> Self {
124 if predicate {
125 PadTemplateBuilder {
126 gtype: Some(gtype),
127 ..self
128 }
129 } else {
130 self
131 }
132 }
133
134 pub fn gtype_if_some(self, gtype: Option<glib::Type>) -> Self {
135 if let Some(gtype) = gtype {
136 self.gtype(gtype)
137 } else {
138 self
139 }
140 }
141
142 #[cfg(feature = "v1_18")]
143 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
144 pub fn documentation_caps(self, documentation_caps: &'a Caps) -> Self {
145 PadTemplateBuilder {
146 documentation_caps: Some(documentation_caps),
147 ..self
148 }
149 }
150
151 #[cfg(feature = "v1_18")]
152 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
153 pub fn documentation_caps_if(self, documentation_caps: &'a Caps, predicate: bool) -> Self {
154 if predicate {
155 PadTemplateBuilder {
156 documentation_caps: Some(documentation_caps),
157 ..self
158 }
159 } else {
160 self
161 }
162 }
163
164 #[cfg(feature = "v1_18")]
165 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
166 pub fn documentation_caps_if_some(self, documentation_caps: Option<&'a Caps>) -> Self {
167 if let Some(documentation_caps) = documentation_caps {
168 self.documentation_caps(documentation_caps)
169 } else {
170 self
171 }
172 }
173
174 pub fn build(self) -> Result<PadTemplate, glib::BoolError> {
175 let templ = if let Some(gtype) = self.gtype {
176 PadTemplate::with_gtype(
177 self.name_template,
178 self.direction,
179 self.presence,
180 self.caps,
181 gtype,
182 )?
183 } else {
184 PadTemplate::new(self.name_template, self.direction, self.presence, self.caps)?
185 };
186
187 #[cfg(feature = "v1_18")]
188 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
189 if let Some(documentation_caps) = self.documentation_caps {
190 unsafe {
191 ffi::gst_pad_template_set_documentation_caps(
192 templ.to_glib_none().0,
193 documentation_caps.to_glib_none().0,
194 );
195 }
196 }
197
198 Ok(templ)
199 }
200}