gstreamer/
ghost_pad.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::translate::*;
4
5use crate::{
6    ffi, prelude::*, FlowError, FlowSuccess, GhostPad, LoggableError, Pad, PadBuilder, PadFlags,
7    PadGetRangeSuccess, PadMode, StaticPadTemplate,
8};
9
10impl GhostPad {
11    #[doc(alias = "gst_ghost_pad_activate_mode_default")]
12    pub fn activate_mode_default<P: IsA<GhostPad>>(
13        pad: &P,
14        parent: Option<&impl IsA<crate::Object>>,
15        mode: PadMode,
16        active: bool,
17    ) -> Result<(), glib::BoolError> {
18        skip_assert_initialized!();
19        unsafe {
20            glib::result_from_gboolean!(
21                ffi::gst_ghost_pad_activate_mode_default(
22                    pad.to_glib_none().0 as *mut ffi::GstPad,
23                    parent.map(|p| p.as_ref()).to_glib_none().0,
24                    mode.into_glib(),
25                    active.into_glib(),
26                ),
27                "Failed to invoke the default activate mode function of the ghost pad"
28            )
29        }
30    }
31
32    #[doc(alias = "gst_ghost_pad_internal_activate_mode_default")]
33    pub fn internal_activate_mode_default<P: IsA<GhostPad>>(
34        pad: &P,
35        parent: Option<&impl IsA<crate::Object>>,
36        mode: PadMode,
37        active: bool,
38    ) -> Result<(), glib::BoolError> {
39        skip_assert_initialized!();
40        unsafe {
41            glib::result_from_gboolean!(
42                ffi::gst_ghost_pad_internal_activate_mode_default(
43                    pad.to_glib_none().0 as *mut ffi::GstPad,
44                    parent.map(|p| p.as_ref()).to_glib_none().0,
45                    mode.into_glib(),
46                    active.into_glib(),
47                ),
48                concat!(
49                    "Failed to invoke the default activate mode function of a proxy pad ",
50                    "that is owned by the ghost pad"
51                )
52            )
53        }
54    }
55
56    // rustdoc-stripper-ignore-next
57    /// Creates a new [`GhostPad`] with an automatically generated name.
58    ///
59    /// The [`Pad`] will be assigned the usual `gst::Object` generated unique name.
60    ///
61    /// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
62    /// and define options.
63    #[doc(alias = "gst_ghost_pad_new_no_target")]
64    pub fn new(direction: crate::PadDirection) -> Self {
65        skip_assert_initialized!();
66        Self::builder(direction).build()
67    }
68
69    // rustdoc-stripper-ignore-next
70    /// Creates a [`PadBuilder`](crate::PadBuilder) with the specified [`PadDirection`](crate::PadDirection).
71    #[doc(alias = "gst_ghost_pad_new_no_target")]
72    pub fn builder(direction: crate::PadDirection) -> PadBuilder<Self> {
73        skip_assert_initialized!();
74        PadBuilder::new(direction)
75    }
76
77    // rustdoc-stripper-ignore-next
78    /// Creates a new [`GhostPad`] from the [`StaticPadTemplate`](crate::StaticPadTemplate).
79    ///
80    /// If the [`StaticPadTemplate`](crate::StaticPadTemplate) has a specific `name_template`,
81    /// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
82    /// the `GhostPad` will automatically be named after the `name_template`.
83    ///
84    /// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
85    /// and define options.
86    ///
87    /// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
88    /// automatically generated unique name.
89    ///
90    /// # Panics
91    ///
92    /// Panics if the `name_template` is a wildcard-name.
93    #[doc(alias = "gst_ghost_pad_new_no_target_from_static_template")]
94    pub fn from_static_template(templ: &StaticPadTemplate) -> Self {
95        skip_assert_initialized!();
96        Self::builder_from_static_template(templ).build()
97    }
98
99    // rustdoc-stripper-ignore-next
100    /// Creates a new [`PadBuilder`](crate::PadBuilder) for a [`GhostPad`] from the [`StaticPadTemplate`](crate::StaticPadTemplate).
101    ///
102    /// If the [`StaticPadTemplate`](crate::StaticPadTemplate) has a specific `name_template`,
103    /// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
104    /// the `GhostPad` will automatically be named after the `name_template`.
105    ///
106    /// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::name_if_some`](crate::PadBuilder::name_if_some)
107    /// to specify a different name.
108    ///
109    /// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
110    /// automatically generated unique name.
111    #[doc(alias = "gst_ghost_pad_new_no_target_from_static_template")]
112    pub fn builder_from_static_template(templ: &StaticPadTemplate) -> PadBuilder<Self> {
113        skip_assert_initialized!();
114        PadBuilder::from_static_template(templ)
115    }
116
117    // rustdoc-stripper-ignore-next
118    /// Creates a new [`GhostPad`] from the [`PadTemplate`](crate::PadTemplate).
119    ///
120    /// If the [`PadTemplate`](crate::PadTemplate) has a specific `name_template`,
121    /// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
122    /// the `GhostPad` will automatically be named after the `name_template`.
123    ///
124    /// Use [`GhostPad::builder_from_template()`] to get a [`PadBuilder`](crate::PadBuilder)
125    /// and define options.
126    ///
127    /// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
128    /// automatically generated unique name.
129    ///
130    /// # Panics
131    ///
132    /// Panics if the `name_template` is a wildcard-name.
133    #[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
134    pub fn from_template(templ: &crate::PadTemplate) -> Self {
135        skip_assert_initialized!();
136        Self::builder_from_template(templ).build()
137    }
138
139    // rustdoc-stripper-ignore-next
140    /// Creates a new [`PadBuilder`](crate::PadBuilder) for a [`GhostPad`] from the [`PadTemplate`](crate::PadTemplate).
141    ///
142    /// If the [`PadTemplate`](crate::PadTemplate) has a specific `name_template`,
143    /// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
144    /// the `GhostPad` will automatically be named after the `name_template`.
145    ///
146    /// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::name_if_some`](crate::PadBuilder::name_if_some)
147    /// to specify a different name.
148    ///
149    /// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
150    /// automatically generated unique name.
151    #[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
152    pub fn builder_from_template(templ: &crate::PadTemplate) -> PadBuilder<Self> {
153        skip_assert_initialized!();
154        PadBuilder::from_template(templ)
155    }
156
157    // rustdoc-stripper-ignore-next
158    /// Creates a new [`GhostPad`] from the specified `target` `Pad`.
159    ///
160    /// The `GhostPad` will automatically be named after the `target` `name`.
161    ///
162    /// Use [`GhostPad::builder_with_target()`] to get a [`PadBuilder`](crate::PadBuilder)
163    /// and define options.
164    ///
165    /// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
166    /// automatically generated unique name.
167    #[doc(alias = "gst_ghost_pad_new")]
168    pub fn with_target<P: IsA<Pad> + IsA<crate::Object>>(
169        target: &P,
170    ) -> Result<Self, glib::BoolError> {
171        skip_assert_initialized!();
172        Ok(Self::builder_with_target(target)?.build())
173    }
174
175    // rustdoc-stripper-ignore-next
176    /// Creates a new [`PadBuilder`](crate::PadBuilder) for a [`GhostPad`] from the specified `target` `Pad`.
177    ///
178    /// The `GhostPad` will automatically be named after the `target` `name`.
179    ///
180    /// Use [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::name_if_some`](crate::PadBuilder::name_if_some)
181    /// to specify a different name.
182    ///
183    /// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
184    /// automatically generated unique name.
185    #[doc(alias = "gst_ghost_pad_new_no_target_from_template")]
186    pub fn builder_with_target<P: IsA<Pad> + IsA<crate::Object>>(
187        target: &P,
188    ) -> Result<PadBuilder<Self>, glib::BoolError> {
189        skip_assert_initialized!();
190        let builder = Self::builder(target.direction());
191        builder.with_target(target)
192    }
193
194    // rustdoc-stripper-ignore-next
195    /// Creates a new [`GhostPad`] from the [`PadTemplate`](crate::PadTemplate)
196    /// with the specified `target` `Pad`.
197    ///
198    /// If the [`PadTemplate`](crate::PadTemplate) has a specific `name_template`,
199    /// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
200    /// the `GhostPad` will automatically be named after the `name_template`.
201    ///
202    /// If the `name_template` is a wildcard-name, then the `target` `name` is used,
203    /// if it is compatible. Otherwise, a specific name must be provided using
204    /// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::name_if_some`](crate::PadBuilder::name_if_some).
205    ///
206    /// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
207    /// automatically generated unique name.
208    #[doc(alias = "gst_ghost_pad_new_from_template")]
209    pub fn from_template_with_target<P: IsA<Pad> + IsA<crate::Object>>(
210        templ: &crate::PadTemplate,
211        target: &P,
212    ) -> Result<Self, glib::BoolError> {
213        skip_assert_initialized!();
214        Ok(Self::builder_from_template_with_target(templ, target)?.build())
215    }
216
217    // rustdoc-stripper-ignore-next
218    /// Creates a new [`PadBuilder`](crate::PadBuilder) for a [`GhostPad`] from the [`PadTemplate`](crate::PadTemplate)
219    /// with the specified `target` `Pad`.
220    ///
221    /// If the [`PadTemplate`](crate::PadTemplate) has a specific `name_template`,
222    /// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
223    /// the `GhostPad` will automatically be named after the `name_template`.
224    ///
225    /// If the `name_template` is a wildcard-name, then the `target` `name` is used,
226    /// if it is compatible. Otherwise, a specific name must be provided using
227    /// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::name_if_some`](crate::PadBuilder::name_if_some).
228    ///
229    /// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
230    /// automatically generated unique name.
231    #[doc(alias = "gst_ghost_pad_new_from_template")]
232    pub fn builder_from_template_with_target<P: IsA<Pad> + IsA<crate::Object>>(
233        templ: &crate::PadTemplate,
234        target: &P,
235    ) -> Result<PadBuilder<Self>, glib::BoolError> {
236        skip_assert_initialized!();
237
238        if target.direction() != templ.direction() {
239            return Err(glib::bool_error!(
240                "Template and target have different directions"
241            ));
242        }
243
244        Self::builder_from_template(templ).with_target(target)
245    }
246}
247
248impl<T: IsA<GhostPad> + IsA<Pad>> PadBuilder<T> {
249    #[doc(alias = "gst_pad_set_activate_function")]
250    pub fn proxy_pad_activate_function<F>(self, func: F) -> Self
251    where
252        F: Fn(&crate::ProxyPad, Option<&crate::Object>) -> Result<(), LoggableError>
253            + Send
254            + Sync
255            + 'static,
256    {
257        unsafe {
258            let proxy = self
259                .pad
260                .unsafe_cast_ref::<crate::ProxyPad>()
261                .internal()
262                .unwrap();
263            proxy.set_activate_function(func);
264        }
265
266        self
267    }
268
269    #[doc(alias = "gst_pad_set_activate_function")]
270    pub fn proxy_pad_activate_function_if_some<F>(self, func: Option<F>) -> Self
271    where
272        F: Fn(&crate::ProxyPad, Option<&crate::Object>) -> Result<(), LoggableError>
273            + Send
274            + Sync
275            + 'static,
276    {
277        if let Some(func) = func {
278            self.proxy_pad_activate_function(func)
279        } else {
280            self
281        }
282    }
283
284    #[doc(alias = "gst_pad_set_activatemode_function")]
285    pub fn proxy_pad_activatemode_function<F>(self, func: F) -> Self
286    where
287        F: Fn(
288                &crate::ProxyPad,
289                Option<&crate::Object>,
290                crate::PadMode,
291                bool,
292            ) -> Result<(), LoggableError>
293            + Send
294            + Sync
295            + 'static,
296    {
297        unsafe {
298            let proxy = self
299                .pad
300                .unsafe_cast_ref::<crate::ProxyPad>()
301                .internal()
302                .unwrap();
303            proxy.set_activatemode_function(func);
304        }
305
306        self
307    }
308
309    #[doc(alias = "gst_pad_set_activatemode_function")]
310    pub fn proxy_pad_activatemode_function_if_some<F>(self, func: Option<F>) -> Self
311    where
312        F: Fn(
313                &crate::ProxyPad,
314                Option<&crate::Object>,
315                crate::PadMode,
316                bool,
317            ) -> Result<(), LoggableError>
318            + Send
319            + Sync
320            + 'static,
321    {
322        if let Some(func) = func {
323            self.proxy_pad_activatemode_function(func)
324        } else {
325            self
326        }
327    }
328
329    #[doc(alias = "gst_pad_set_chain_function")]
330    pub fn proxy_pad_chain_function<F>(self, func: F) -> Self
331    where
332        F: Fn(
333                &crate::ProxyPad,
334                Option<&crate::Object>,
335                crate::Buffer,
336            ) -> Result<FlowSuccess, FlowError>
337            + Send
338            + Sync
339            + 'static,
340    {
341        unsafe {
342            let proxy = self
343                .pad
344                .unsafe_cast_ref::<crate::ProxyPad>()
345                .internal()
346                .unwrap();
347            proxy.set_chain_function(func);
348        }
349
350        self
351    }
352
353    #[doc(alias = "gst_pad_set_chain_function")]
354    pub fn proxy_pad_chain_function_if_some<F>(self, func: Option<F>) -> Self
355    where
356        F: Fn(
357                &crate::ProxyPad,
358                Option<&crate::Object>,
359                crate::Buffer,
360            ) -> Result<FlowSuccess, FlowError>
361            + Send
362            + Sync
363            + 'static,
364    {
365        if let Some(func) = func {
366            self.proxy_pad_chain_function(func)
367        } else {
368            self
369        }
370    }
371
372    #[doc(alias = "gst_pad_set_chain_list_function")]
373    pub fn proxy_pad_chain_list_function<F>(self, func: F) -> Self
374    where
375        F: Fn(
376                &crate::ProxyPad,
377                Option<&crate::Object>,
378                crate::BufferList,
379            ) -> Result<FlowSuccess, FlowError>
380            + Send
381            + Sync
382            + 'static,
383    {
384        unsafe {
385            let proxy = self
386                .pad
387                .unsafe_cast_ref::<crate::ProxyPad>()
388                .internal()
389                .unwrap();
390            proxy.set_chain_list_function(func);
391        }
392
393        self
394    }
395
396    #[doc(alias = "gst_pad_set_chain_list_function")]
397    pub fn proxy_pad_chain_list_function_if_some<F>(self, func: Option<F>) -> Self
398    where
399        F: Fn(
400                &crate::ProxyPad,
401                Option<&crate::Object>,
402                crate::BufferList,
403            ) -> Result<FlowSuccess, FlowError>
404            + Send
405            + Sync
406            + 'static,
407    {
408        if let Some(func) = func {
409            self.proxy_pad_chain_list_function(func)
410        } else {
411            self
412        }
413    }
414
415    #[doc(alias = "gst_pad_set_event_function")]
416    pub fn proxy_pad_event_function<F>(self, func: F) -> Self
417    where
418        F: Fn(&crate::ProxyPad, Option<&crate::Object>, crate::Event) -> bool
419            + Send
420            + Sync
421            + 'static,
422    {
423        unsafe {
424            let proxy = self
425                .pad
426                .unsafe_cast_ref::<crate::ProxyPad>()
427                .internal()
428                .unwrap();
429            proxy.set_event_function(func);
430        }
431
432        self
433    }
434
435    #[doc(alias = "gst_pad_set_event_function")]
436    pub fn proxy_pad_event_function_if_some<F>(self, func: Option<F>) -> Self
437    where
438        F: Fn(&crate::ProxyPad, Option<&crate::Object>, crate::Event) -> bool
439            + Send
440            + Sync
441            + 'static,
442    {
443        if let Some(func) = func {
444            self.proxy_pad_event_function(func)
445        } else {
446            self
447        }
448    }
449
450    #[doc(alias = "gst_pad_set_event_full_function")]
451    pub fn proxy_pad_event_full_function<F>(self, func: F) -> Self
452    where
453        F: Fn(
454                &crate::ProxyPad,
455                Option<&crate::Object>,
456                crate::Event,
457            ) -> Result<FlowSuccess, FlowError>
458            + Send
459            + Sync
460            + 'static,
461    {
462        unsafe {
463            let proxy = self
464                .pad
465                .unsafe_cast_ref::<crate::ProxyPad>()
466                .internal()
467                .unwrap();
468            proxy.set_event_full_function(func);
469        }
470
471        self
472    }
473
474    #[doc(alias = "gst_pad_set_event_full_function")]
475    pub fn proxy_pad_event_full_function_if_some<F>(self, func: Option<F>) -> Self
476    where
477        F: Fn(
478                &crate::ProxyPad,
479                Option<&crate::Object>,
480                crate::Event,
481            ) -> Result<FlowSuccess, FlowError>
482            + Send
483            + Sync
484            + 'static,
485    {
486        if let Some(func) = func {
487            self.proxy_pad_event_full_function(func)
488        } else {
489            self
490        }
491    }
492
493    #[doc(alias = "gst_pad_set_getrange_function")]
494    pub fn proxy_pad_getrange_function<F>(self, func: F) -> Self
495    where
496        F: Fn(
497                &crate::ProxyPad,
498                Option<&crate::Object>,
499                u64,
500                Option<&mut crate::BufferRef>,
501                u32,
502            ) -> Result<PadGetRangeSuccess, crate::FlowError>
503            + Send
504            + Sync
505            + 'static,
506    {
507        unsafe {
508            let proxy = self
509                .pad
510                .unsafe_cast_ref::<crate::ProxyPad>()
511                .internal()
512                .unwrap();
513            proxy.set_getrange_function(func);
514        }
515
516        self
517    }
518
519    #[doc(alias = "gst_pad_set_getrange_function")]
520    pub fn proxy_pad_getrange_function_if_some<F>(self, func: Option<F>) -> Self
521    where
522        F: Fn(
523                &crate::ProxyPad,
524                Option<&crate::Object>,
525                u64,
526                Option<&mut crate::BufferRef>,
527                u32,
528            ) -> Result<PadGetRangeSuccess, crate::FlowError>
529            + Send
530            + Sync
531            + 'static,
532    {
533        if let Some(func) = func {
534            self.proxy_pad_getrange_function(func)
535        } else {
536            self
537        }
538    }
539
540    #[doc(alias = "gst_pad_set_iterate_internal_links_function")]
541    pub fn proxy_pad_iterate_internal_links_function<F>(self, func: F) -> Self
542    where
543        F: Fn(&crate::ProxyPad, Option<&crate::Object>) -> crate::Iterator<Pad>
544            + Send
545            + Sync
546            + 'static,
547    {
548        unsafe {
549            let proxy = self
550                .pad
551                .unsafe_cast_ref::<crate::ProxyPad>()
552                .internal()
553                .unwrap();
554            proxy.set_iterate_internal_links_function(func);
555        }
556
557        self
558    }
559
560    #[doc(alias = "gst_pad_set_iterate_internal_links_function")]
561    pub fn proxy_pad_iterate_internal_links_function_if_some<F>(self, func: Option<F>) -> Self
562    where
563        F: Fn(&crate::ProxyPad, Option<&crate::Object>) -> crate::Iterator<Pad>
564            + Send
565            + Sync
566            + 'static,
567    {
568        if let Some(func) = func {
569            self.proxy_pad_iterate_internal_links_function(func)
570        } else {
571            self
572        }
573    }
574
575    #[doc(alias = "gst_pad_set_link_function")]
576    pub fn proxy_pad_link_function<F>(self, func: F) -> Self
577    where
578        F: Fn(
579                &crate::ProxyPad,
580                Option<&crate::Object>,
581                &Pad,
582            ) -> Result<crate::PadLinkSuccess, crate::PadLinkError>
583            + Send
584            + Sync
585            + 'static,
586    {
587        unsafe {
588            let proxy = self
589                .pad
590                .unsafe_cast_ref::<crate::ProxyPad>()
591                .internal()
592                .unwrap();
593            proxy.set_link_function(func);
594        }
595
596        self
597    }
598
599    #[doc(alias = "gst_pad_set_link_function")]
600    pub fn proxy_pad_link_function_if_some<F>(self, func: Option<F>) -> Self
601    where
602        F: Fn(
603                &crate::ProxyPad,
604                Option<&crate::Object>,
605                &Pad,
606            ) -> Result<crate::PadLinkSuccess, crate::PadLinkError>
607            + Send
608            + Sync
609            + 'static,
610    {
611        if let Some(func) = func {
612            self.proxy_pad_link_function(func)
613        } else {
614            self
615        }
616    }
617
618    #[doc(alias = "gst_pad_set_query_function")]
619    pub fn proxy_pad_query_function<F>(self, func: F) -> Self
620    where
621        F: Fn(&crate::ProxyPad, Option<&crate::Object>, &mut crate::QueryRef) -> bool
622            + Send
623            + Sync
624            + 'static,
625    {
626        unsafe {
627            let proxy = self
628                .pad
629                .unsafe_cast_ref::<crate::ProxyPad>()
630                .internal()
631                .unwrap();
632            proxy.set_query_function(func);
633        }
634
635        self
636    }
637
638    #[doc(alias = "gst_pad_set_query_function")]
639    pub fn proxy_pad_query_function_if_some<F>(self, func: Option<F>) -> Self
640    where
641        F: Fn(&crate::ProxyPad, Option<&crate::Object>, &mut crate::QueryRef) -> bool
642            + Send
643            + Sync
644            + 'static,
645    {
646        if let Some(func) = func {
647            self.proxy_pad_query_function(func)
648        } else {
649            self
650        }
651    }
652
653    #[doc(alias = "gst_pad_set_unlink_function")]
654    pub fn proxy_pad_unlink_function<F>(self, func: F) -> Self
655    where
656        F: Fn(&crate::ProxyPad, Option<&crate::Object>) + Send + Sync + 'static,
657    {
658        unsafe {
659            let proxy = self
660                .pad
661                .unsafe_cast_ref::<crate::ProxyPad>()
662                .internal()
663                .unwrap();
664            proxy.set_unlink_function(func);
665        }
666
667        self
668    }
669
670    #[doc(alias = "gst_pad_set_unlink_function")]
671    pub fn proxy_pad_unlink_function_if_some<F>(self, func: Option<F>) -> Self
672    where
673        F: Fn(&crate::ProxyPad, Option<&crate::Object>) + Send + Sync + 'static,
674    {
675        if let Some(func) = func {
676            self.proxy_pad_unlink_function(func)
677        } else {
678            self
679        }
680    }
681
682    pub fn proxy_pad_flags(self, flags: PadFlags) -> Self {
683        unsafe {
684            let proxy = self
685                .pad
686                .unsafe_cast_ref::<crate::ProxyPad>()
687                .internal()
688                .unwrap();
689            proxy.set_pad_flags(flags);
690        }
691
692        self
693    }
694
695    pub fn proxy_pad_flags_if_some(self, flags: Option<PadFlags>) -> Self {
696        if let Some(flags) = flags {
697            self.proxy_pad_flags(flags)
698        } else {
699            self
700        }
701    }
702
703    // rustdoc-stripper-ignore-next
704    /// Specifies a `target` [`Pad`](crate::Pad) for the [`GhostPad`].
705    ///
706    /// If the [`PadBuilder`](crate::PadBuilder) was created from
707    /// a [`PadTemplate`](crate::PadTemplate) and the `PadTemplate` has a specific `name_template`,
708    /// i.e. if it's not a wildcard-name containing `%u`, `%s` or `%d`,
709    /// the `GhostPad` will automatically be named after the `name_template`.
710    ///
711    /// If the `name_template` is a wildcard-name, then the `target` `name` is used,
712    /// if it is compatible. Otherwise, a specific name must be provided using
713    /// [`PadBuilder::name`](crate::PadBuilder::name) or [`PadBuilder::name_if_some`](crate::PadBuilder::name_if_some).
714    ///
715    /// Use [`generated_name()`](crate::PadBuilder::generated_name`) to keep the `gst::Object`
716    /// automatically generated unique name.
717    pub fn with_target<P: IsA<Pad> + IsA<crate::Object>>(
718        mut self,
719        target: &P,
720    ) -> Result<Self, glib::BoolError> {
721        assert_eq!(self.pad.direction(), target.direction());
722
723        self.pad.set_target(Some(target))?;
724        self.name =
725            crate::pad::PadBuilderName::CandidateForWildcardTemplate(target.name().to_string());
726
727        Ok(self)
728    }
729}
730
731#[cfg(test)]
732mod tests {
733    use super::*;
734
735    #[test]
736    fn no_template_no_target() {
737        crate::init().unwrap();
738
739        let ghost_pad = GhostPad::new(crate::PadDirection::Sink);
740        assert!(ghost_pad.name().starts_with("ghostpad"));
741
742        let ghost_pad = GhostPad::builder(crate::PadDirection::Sink).build();
743        assert!(ghost_pad.name().starts_with("ghostpad"));
744
745        let ghost_pad = GhostPad::builder(crate::PadDirection::Sink)
746            .name("sink")
747            .build();
748        assert_eq!(ghost_pad.name(), "sink");
749    }
750
751    #[test]
752    fn from_template() {
753        crate::init().unwrap();
754
755        let caps = crate::Caps::new_any();
756        let wildcard_templ = crate::PadTemplate::new(
757            "sink_%u",
758            crate::PadDirection::Sink,
759            crate::PadPresence::Request,
760            &caps,
761        )
762        .unwrap();
763
764        let ghost_pad = GhostPad::builder_from_template(&wildcard_templ)
765            .name("my-ghostpad")
766            .build();
767        assert_eq!(ghost_pad.name(), "my-ghostpad");
768
769        let caps = crate::Caps::new_any();
770        let templ = crate::PadTemplate::new(
771            "sink",
772            crate::PadDirection::Sink,
773            crate::PadPresence::Always,
774            &caps,
775        )
776        .unwrap();
777
778        let ghost_pad = GhostPad::from_template(&templ);
779        assert_eq!(ghost_pad.name(), "sink");
780
781        let ghost_pad = GhostPad::builder_from_template(&templ).build();
782        assert!(ghost_pad.name().starts_with("sink"));
783
784        let ghost_pad = GhostPad::builder_from_template(&templ)
785            .name("my-sink")
786            .build();
787        assert_eq!(ghost_pad.name(), "my-sink");
788    }
789
790    #[test]
791    #[should_panic]
792    fn from_template_missing_name() {
793        crate::init().unwrap();
794
795        let caps = crate::Caps::new_any();
796        let templ = crate::PadTemplate::new(
797            "audio_%u",
798            crate::PadDirection::Sink,
799            crate::PadPresence::Request,
800            &caps,
801        )
802        .unwrap();
803
804        // Panic: attempt to build from a wildcard-named template
805        //        without providing a name.
806        let _ghost_pad = GhostPad::from_template(&templ);
807    }
808
809    #[test]
810    #[should_panic]
811    fn from_template_builder_missing_name() {
812        crate::init().unwrap();
813
814        let caps = crate::Caps::new_any();
815        let templ = crate::PadTemplate::new(
816            "audio_%u",
817            crate::PadDirection::Sink,
818            crate::PadPresence::Request,
819            &caps,
820        )
821        .unwrap();
822
823        // Panic: attempt to build from a wildcard-named template
824        //        without providing a name.
825        let _ghost_pad = GhostPad::builder_from_template(&templ).build();
826    }
827
828    #[test]
829    fn with_target() {
830        crate::init().unwrap();
831
832        let caps = crate::Caps::new_any();
833        let templ = crate::PadTemplate::new(
834            "test",
835            crate::PadDirection::Sink,
836            crate::PadPresence::Always,
837            &caps,
838        )
839        .unwrap();
840
841        let target = crate::Pad::builder_from_template(&templ).build();
842        let ghost_pad = GhostPad::with_target(&target).unwrap();
843        assert_eq!(ghost_pad.name(), "test");
844
845        let target = crate::Pad::from_template(&templ);
846        let ghost_pad = GhostPad::builder_with_target(&target).unwrap().build();
847        assert_eq!(ghost_pad.name(), "test");
848
849        let target = crate::Pad::from_template(&templ);
850        let ghost_pad = GhostPad::builder_with_target(&target)
851            .unwrap()
852            .name("ghost_test")
853            .build();
854        assert_eq!(ghost_pad.name(), "ghost_test");
855
856        let target = crate::Pad::from_template(&templ);
857        let ghost_pad = GhostPad::builder_with_target(&target)
858            .unwrap()
859            .generated_name()
860            .build();
861        assert!(ghost_pad.name().starts_with("ghostpad"));
862    }
863
864    #[test]
865    fn from_template_with_target() {
866        crate::init().unwrap();
867
868        let caps = crate::Caps::new_any();
869        let sink_templ = crate::PadTemplate::new(
870            "sink",
871            crate::PadDirection::Sink,
872            crate::PadPresence::Always,
873            &caps,
874        )
875        .unwrap();
876
877        // # No conversion specifier, Always template
878        let ghost_templ = crate::PadTemplate::new(
879            "ghost_sink",
880            crate::PadDirection::Sink,
881            crate::PadPresence::Always,
882            &caps,
883        )
884        .unwrap();
885
886        let target = crate::Pad::from_template(&sink_templ);
887        let ghost_pad = GhostPad::from_template_with_target(&ghost_templ, &target).unwrap();
888        assert_eq!(ghost_pad.name(), "ghost_sink");
889
890        let target = crate::Pad::from_template(&sink_templ);
891        let ghost_pad = GhostPad::builder_from_template_with_target(&ghost_templ, &target)
892            .unwrap()
893            .build();
894        assert_eq!(ghost_pad.name(), "ghost_sink");
895
896        let target = crate::Pad::from_template(&sink_templ);
897        let ghost_pad = GhostPad::builder_from_template_with_target(&ghost_templ, &target)
898            .unwrap()
899            .name("my-sink")
900            .build();
901        assert_eq!(ghost_pad.name(), "my-sink");
902
903        let target = crate::Pad::from_template(&sink_templ);
904        let ghost_pad = GhostPad::builder_from_template_with_target(&ghost_templ, &target)
905            .unwrap()
906            .generated_name()
907            .build();
908        assert!(ghost_pad.name().starts_with("ghostpad"));
909
910        // # Request template %u
911        let wildcard_u_templ = crate::PadTemplate::new(
912            "sink_%u",
913            crate::PadDirection::Sink,
914            crate::PadPresence::Request,
915            &caps,
916        )
917        .unwrap();
918
919        // ## Incompatible target but specific name
920        let target = crate::Pad::from_template(&sink_templ);
921        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_u_templ, &target)
922            .unwrap()
923            .name("sink_0")
924            .build();
925        assert_eq!(ghost_pad.name(), "sink_0");
926
927        // ## Compatible target
928        let sink_0_templ = crate::PadTemplate::new(
929            "sink_0",
930            crate::PadDirection::Sink,
931            crate::PadPresence::Always,
932            &caps,
933        )
934        .unwrap();
935        let target = crate::Pad::from_template(&sink_0_templ);
936        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_u_templ, &target)
937            .unwrap()
938            .build();
939        assert_eq!(ghost_pad.name(), "sink_0");
940
941        let target = crate::Pad::from_template(&sink_0_templ);
942        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_u_templ, &target)
943            .unwrap()
944            .generated_name()
945            .build();
946        assert!(ghost_pad.name().starts_with("ghostpad"));
947
948        // # Request template %d_%u
949        let wildcard_u_templ = crate::PadTemplate::new(
950            "sink_%d_%u",
951            crate::PadDirection::Sink,
952            crate::PadPresence::Request,
953            &caps,
954        )
955        .unwrap();
956
957        // ## Incompatible target but specific name
958        let target = crate::Pad::from_template(&sink_templ);
959        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_u_templ, &target)
960            .unwrap()
961            .name("sink_-1_0")
962            .build();
963        assert_eq!(ghost_pad.name(), "sink_-1_0");
964
965        // ## Compatible target
966        let sink_m2_0_templ = crate::PadTemplate::new(
967            "sink_-2_0",
968            crate::PadDirection::Sink,
969            crate::PadPresence::Always,
970            &caps,
971        )
972        .unwrap();
973        let target = crate::Pad::from_template(&sink_m2_0_templ);
974        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_u_templ, &target)
975            .unwrap()
976            .build();
977        assert_eq!(ghost_pad.name(), "sink_-2_0");
978
979        // # Request template %s
980        let wildcard_s_templ = crate::PadTemplate::new(
981            "sink_%s",
982            crate::PadDirection::Sink,
983            crate::PadPresence::Request,
984            &caps,
985        )
986        .unwrap();
987
988        // ## Incompatible target but specific name
989        let target = crate::Pad::from_template(&sink_templ);
990        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_s_templ, &target)
991            .unwrap()
992            .name("sink_ghost_test")
993            .build();
994        assert_eq!(ghost_pad.name(), "sink_ghost_test");
995
996        // ## Compatible target
997        let sink_test_templ = crate::PadTemplate::new(
998            "sink_test",
999            crate::PadDirection::Sink,
1000            crate::PadPresence::Always,
1001            &caps,
1002        )
1003        .unwrap();
1004        let target = crate::Pad::from_template(&sink_test_templ);
1005        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_s_templ, &target)
1006            .unwrap()
1007            .build();
1008        assert_eq!(ghost_pad.name(), "sink_test");
1009    }
1010
1011    #[test]
1012    #[should_panic]
1013    fn from_template_with_target_incompatible_prefix() {
1014        crate::init().unwrap();
1015
1016        let caps = crate::Caps::new_any();
1017        let wildcard_templ = crate::PadTemplate::new(
1018            "sink_%u",
1019            crate::PadDirection::Sink,
1020            crate::PadPresence::Request,
1021            &caps,
1022        )
1023        .unwrap();
1024
1025        let templ = crate::PadTemplate::new(
1026            "audio_0",
1027            crate::PadDirection::Sink,
1028            crate::PadPresence::Always,
1029            &caps,
1030        )
1031        .unwrap();
1032
1033        let target = crate::Pad::from_template(&templ);
1034        // Panic: attempt to build from a wildcard-named template
1035        //        with a target name with a different prefix
1036        //        without providing a name.
1037        let _ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_templ, &target)
1038            .unwrap()
1039            .build();
1040    }
1041
1042    #[test]
1043    #[should_panic]
1044    fn from_template_with_target_missing_part() {
1045        crate::init().unwrap();
1046
1047        let caps = crate::Caps::new_any();
1048        let wildcard_templ = crate::PadTemplate::new(
1049            "sink_%u_%s",
1050            crate::PadDirection::Sink,
1051            crate::PadPresence::Request,
1052            &caps,
1053        )
1054        .unwrap();
1055
1056        let templ = crate::PadTemplate::new(
1057            "sink_0",
1058            crate::PadDirection::Sink,
1059            crate::PadPresence::Always,
1060            &caps,
1061        )
1062        .unwrap();
1063
1064        let target = crate::Pad::from_template(&templ);
1065        // Panic: attempt to build from a wildcard-named template
1066        //        with a target name missing a part
1067        //        without providing a name.
1068        let _ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_templ, &target)
1069            .unwrap()
1070            .build();
1071    }
1072
1073    #[test]
1074    #[should_panic]
1075    fn from_template_with_target_incompatible_conversion_unsigned() {
1076        crate::init().unwrap();
1077
1078        let caps = crate::Caps::new_any();
1079        let wildcard_templ = crate::PadTemplate::new(
1080            "sink_%u",
1081            crate::PadDirection::Sink,
1082            crate::PadPresence::Request,
1083            &caps,
1084        )
1085        .unwrap();
1086
1087        let templ = crate::PadTemplate::new(
1088            "sink_-1",
1089            crate::PadDirection::Sink,
1090            crate::PadPresence::Always,
1091            &caps,
1092        )
1093        .unwrap();
1094
1095        let target = crate::Pad::from_template(&templ);
1096        // Panic: attempt to build from a wildcard-named template
1097        //        with a target name %d, expecting %u
1098        //        without providing a name.
1099        let _ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_templ, &target)
1100            .unwrap()
1101            .build();
1102    }
1103
1104    #[test]
1105    #[should_panic]
1106    fn from_template_with_target_incompatible_conversion_decimal() {
1107        crate::init().unwrap();
1108
1109        let caps = crate::Caps::new_any();
1110        let wildcard_templ = crate::PadTemplate::new(
1111            "sink_%u",
1112            crate::PadDirection::Sink,
1113            crate::PadPresence::Request,
1114            &caps,
1115        )
1116        .unwrap();
1117
1118        let templ = crate::PadTemplate::new(
1119            "sink_test",
1120            crate::PadDirection::Sink,
1121            crate::PadPresence::Always,
1122            &caps,
1123        )
1124        .unwrap();
1125
1126        let target = crate::Pad::from_template(&templ);
1127        // Panic: attempt to build from a wildcard-named template
1128        //        with a target name with %s, expecting %d
1129        //        without providing a name.
1130        let _ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_templ, &target)
1131            .unwrap()
1132            .build();
1133    }
1134
1135    #[test]
1136    #[should_panic]
1137    fn from_template_with_target_incompatible_missing_decimal() {
1138        crate::init().unwrap();
1139
1140        let caps = crate::Caps::new_any();
1141        let wildcard_templ = crate::PadTemplate::new(
1142            "sink_%d",
1143            crate::PadDirection::Sink,
1144            crate::PadPresence::Request,
1145            &caps,
1146        )
1147        .unwrap();
1148
1149        let templ = crate::PadTemplate::new(
1150            "sink_",
1151            crate::PadDirection::Sink,
1152            crate::PadPresence::Always,
1153            &caps,
1154        )
1155        .unwrap();
1156
1157        let target = crate::Pad::from_template(&templ);
1158        // Panic: attempt to build from a wildcard-named template
1159        //        with a target name missing a number, expecting %d
1160        //        without providing a name.
1161        let _ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_templ, &target)
1162            .unwrap()
1163            .build();
1164    }
1165}