gstreamer/
pad_template.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use 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}