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    FlowError, FlowSuccess, GhostPad, LoggableError, Pad, PadBuilder, PadFlags, PadGetRangeSuccess,
7    PadMode, StaticPadTemplate, ffi, prelude::*,
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        if !matches!(self.name, crate::pad::PadBuilderName::UserDefined(_)) {
725            self.name =
726                crate::pad::PadBuilderName::CandidateForWildcardTemplate(target.name().to_string());
727        }
728
729        Ok(self)
730    }
731}
732
733#[cfg(test)]
734mod tests {
735    use super::*;
736
737    #[test]
738    fn no_template_no_target() {
739        crate::init().unwrap();
740
741        let ghost_pad = GhostPad::new(crate::PadDirection::Sink);
742        assert!(ghost_pad.name().starts_with("ghostpad"));
743
744        let ghost_pad = GhostPad::builder(crate::PadDirection::Sink).build();
745        assert!(ghost_pad.name().starts_with("ghostpad"));
746
747        let ghost_pad = GhostPad::builder(crate::PadDirection::Sink)
748            .name("sink")
749            .build();
750        assert_eq!(ghost_pad.name(), "sink");
751    }
752
753    #[test]
754    fn from_template() {
755        crate::init().unwrap();
756
757        let caps = crate::Caps::new_any();
758        let wildcard_templ = crate::PadTemplate::new(
759            "sink_%u",
760            crate::PadDirection::Sink,
761            crate::PadPresence::Request,
762            &caps,
763        )
764        .unwrap();
765
766        let ghost_pad = GhostPad::builder_from_template(&wildcard_templ)
767            .name("my-ghostpad")
768            .build();
769        assert_eq!(ghost_pad.name(), "my-ghostpad");
770
771        let caps = crate::Caps::new_any();
772        let templ = crate::PadTemplate::new(
773            "sink",
774            crate::PadDirection::Sink,
775            crate::PadPresence::Always,
776            &caps,
777        )
778        .unwrap();
779
780        let ghost_pad = GhostPad::from_template(&templ);
781        assert_eq!(ghost_pad.name(), "sink");
782
783        let ghost_pad = GhostPad::builder_from_template(&templ).build();
784        assert!(ghost_pad.name().starts_with("sink"));
785
786        let ghost_pad = GhostPad::builder_from_template(&templ)
787            .name("my-sink")
788            .build();
789        assert_eq!(ghost_pad.name(), "my-sink");
790    }
791
792    #[test]
793    #[should_panic]
794    fn from_template_missing_name() {
795        crate::init().unwrap();
796
797        let caps = crate::Caps::new_any();
798        let templ = crate::PadTemplate::new(
799            "audio_%u",
800            crate::PadDirection::Sink,
801            crate::PadPresence::Request,
802            &caps,
803        )
804        .unwrap();
805
806        // Panic: attempt to build from a wildcard-named template
807        //        without providing a name.
808        let _ghost_pad = GhostPad::from_template(&templ);
809    }
810
811    #[test]
812    #[should_panic]
813    fn from_template_builder_missing_name() {
814        crate::init().unwrap();
815
816        let caps = crate::Caps::new_any();
817        let templ = crate::PadTemplate::new(
818            "audio_%u",
819            crate::PadDirection::Sink,
820            crate::PadPresence::Request,
821            &caps,
822        )
823        .unwrap();
824
825        // Panic: attempt to build from a wildcard-named template
826        //        without providing a name.
827        let _ghost_pad = GhostPad::builder_from_template(&templ).build();
828    }
829
830    #[test]
831    fn with_target() {
832        crate::init().unwrap();
833
834        let caps = crate::Caps::new_any();
835        let templ = crate::PadTemplate::new(
836            "test",
837            crate::PadDirection::Sink,
838            crate::PadPresence::Always,
839            &caps,
840        )
841        .unwrap();
842
843        let target = crate::Pad::builder_from_template(&templ).build();
844        let ghost_pad = GhostPad::with_target(&target).unwrap();
845        assert_eq!(ghost_pad.name(), "test");
846
847        let target = crate::Pad::from_template(&templ);
848        let ghost_pad = GhostPad::builder_with_target(&target).unwrap().build();
849        assert_eq!(ghost_pad.name(), "test");
850
851        let target = crate::Pad::from_template(&templ);
852        let ghost_pad = GhostPad::builder_with_target(&target)
853            .unwrap()
854            .name("ghost_test")
855            .build();
856        assert_eq!(ghost_pad.name(), "ghost_test");
857
858        let target = crate::Pad::from_template(&templ);
859        let ghost_pad = GhostPad::builder_with_target(&target)
860            .unwrap()
861            .generated_name()
862            .build();
863        assert!(ghost_pad.name().starts_with("ghostpad"));
864
865        let target = crate::Pad::from_template(&templ);
866        let ghost_pad = GhostPad::builder_from_template(&templ)
867            .with_target(&target)
868            .unwrap()
869            .build();
870        assert_eq!(ghost_pad.name(), "test");
871
872        let target = crate::Pad::from_template(&templ);
873        let ghost_pad = GhostPad::builder_from_template(&templ)
874            .name("ghost_test")
875            .with_target(&target)
876            .unwrap()
877            .build();
878        assert_eq!(ghost_pad.name(), "ghost_test");
879
880        let target = crate::Pad::from_template(&templ);
881        let ghost_pad = GhostPad::builder_from_template(&templ)
882            .with_target(&target)
883            .unwrap()
884            .name("ghost_test")
885            .build();
886        assert_eq!(ghost_pad.name(), "ghost_test");
887
888        let target = crate::Pad::from_template(&templ);
889        let ghost_pad = GhostPad::builder_from_template(&templ)
890            .with_target(&target)
891            .unwrap()
892            .generated_name()
893            .build();
894        assert!(ghost_pad.name().starts_with("ghostpad"));
895    }
896
897    #[test]
898    fn from_template_with_target() {
899        crate::init().unwrap();
900
901        let caps = crate::Caps::new_any();
902        let sink_templ = crate::PadTemplate::new(
903            "sink",
904            crate::PadDirection::Sink,
905            crate::PadPresence::Always,
906            &caps,
907        )
908        .unwrap();
909
910        // # No conversion specifier, Always template
911        let ghost_templ = crate::PadTemplate::new(
912            "ghost_sink",
913            crate::PadDirection::Sink,
914            crate::PadPresence::Always,
915            &caps,
916        )
917        .unwrap();
918
919        let target = crate::Pad::from_template(&sink_templ);
920        let ghost_pad = GhostPad::from_template_with_target(&ghost_templ, &target).unwrap();
921        assert_eq!(ghost_pad.name(), "ghost_sink");
922
923        let target = crate::Pad::from_template(&sink_templ);
924        let ghost_pad = GhostPad::builder_from_template_with_target(&ghost_templ, &target)
925            .unwrap()
926            .build();
927        assert_eq!(ghost_pad.name(), "ghost_sink");
928
929        let target = crate::Pad::from_template(&sink_templ);
930        let ghost_pad = GhostPad::builder_from_template_with_target(&ghost_templ, &target)
931            .unwrap()
932            .name("my-sink")
933            .build();
934        assert_eq!(ghost_pad.name(), "my-sink");
935
936        let target = crate::Pad::from_template(&sink_templ);
937        let ghost_pad = GhostPad::builder_from_template_with_target(&ghost_templ, &target)
938            .unwrap()
939            .generated_name()
940            .build();
941        assert!(ghost_pad.name().starts_with("ghostpad"));
942
943        // # Request template %u
944        let wildcard_u_templ = crate::PadTemplate::new(
945            "sink_%u",
946            crate::PadDirection::Sink,
947            crate::PadPresence::Request,
948            &caps,
949        )
950        .unwrap();
951
952        // ## Incompatible target but specific name
953        let target = crate::Pad::from_template(&sink_templ);
954        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_u_templ, &target)
955            .unwrap()
956            .name("sink_0")
957            .build();
958        assert_eq!(ghost_pad.name(), "sink_0");
959
960        // ## Compatible target
961        let sink_0_templ = crate::PadTemplate::new(
962            "sink_0",
963            crate::PadDirection::Sink,
964            crate::PadPresence::Always,
965            &caps,
966        )
967        .unwrap();
968        let target = crate::Pad::from_template(&sink_0_templ);
969        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_u_templ, &target)
970            .unwrap()
971            .build();
972        assert_eq!(ghost_pad.name(), "sink_0");
973
974        let target = crate::Pad::from_template(&sink_0_templ);
975        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_u_templ, &target)
976            .unwrap()
977            .generated_name()
978            .build();
979        assert!(ghost_pad.name().starts_with("ghostpad"));
980
981        // # Request template %d_%u
982        let wildcard_u_templ = crate::PadTemplate::new(
983            "sink_%d_%u",
984            crate::PadDirection::Sink,
985            crate::PadPresence::Request,
986            &caps,
987        )
988        .unwrap();
989
990        // ## Incompatible target but specific name
991        let target = crate::Pad::from_template(&sink_templ);
992        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_u_templ, &target)
993            .unwrap()
994            .name("sink_-1_0")
995            .build();
996        assert_eq!(ghost_pad.name(), "sink_-1_0");
997
998        // ## Compatible target
999        let sink_m2_0_templ = crate::PadTemplate::new(
1000            "sink_-2_0",
1001            crate::PadDirection::Sink,
1002            crate::PadPresence::Always,
1003            &caps,
1004        )
1005        .unwrap();
1006        let target = crate::Pad::from_template(&sink_m2_0_templ);
1007        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_u_templ, &target)
1008            .unwrap()
1009            .build();
1010        assert_eq!(ghost_pad.name(), "sink_-2_0");
1011
1012        // # Request template %s
1013        let wildcard_s_templ = crate::PadTemplate::new(
1014            "sink_%s",
1015            crate::PadDirection::Sink,
1016            crate::PadPresence::Request,
1017            &caps,
1018        )
1019        .unwrap();
1020
1021        // ## Incompatible target but specific name
1022        let target = crate::Pad::from_template(&sink_templ);
1023        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_s_templ, &target)
1024            .unwrap()
1025            .name("sink_ghost_test")
1026            .build();
1027        assert_eq!(ghost_pad.name(), "sink_ghost_test");
1028
1029        // ## Compatible target
1030        let sink_test_templ = crate::PadTemplate::new(
1031            "sink_test",
1032            crate::PadDirection::Sink,
1033            crate::PadPresence::Always,
1034            &caps,
1035        )
1036        .unwrap();
1037        let target = crate::Pad::from_template(&sink_test_templ);
1038        let ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_s_templ, &target)
1039            .unwrap()
1040            .build();
1041        assert_eq!(ghost_pad.name(), "sink_test");
1042    }
1043
1044    #[test]
1045    #[should_panic]
1046    fn from_template_with_target_incompatible_prefix() {
1047        crate::init().unwrap();
1048
1049        let caps = crate::Caps::new_any();
1050        let wildcard_templ = crate::PadTemplate::new(
1051            "sink_%u",
1052            crate::PadDirection::Sink,
1053            crate::PadPresence::Request,
1054            &caps,
1055        )
1056        .unwrap();
1057
1058        let templ = crate::PadTemplate::new(
1059            "audio_0",
1060            crate::PadDirection::Sink,
1061            crate::PadPresence::Always,
1062            &caps,
1063        )
1064        .unwrap();
1065
1066        let target = crate::Pad::from_template(&templ);
1067        // Panic: attempt to build from a wildcard-named template
1068        //        with a target name with a different prefix
1069        //        without providing a name.
1070        let _ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_templ, &target)
1071            .unwrap()
1072            .build();
1073    }
1074
1075    #[test]
1076    #[should_panic]
1077    fn from_template_with_target_missing_part() {
1078        crate::init().unwrap();
1079
1080        let caps = crate::Caps::new_any();
1081        let wildcard_templ = crate::PadTemplate::new(
1082            "sink_%u_%s",
1083            crate::PadDirection::Sink,
1084            crate::PadPresence::Request,
1085            &caps,
1086        )
1087        .unwrap();
1088
1089        let templ = crate::PadTemplate::new(
1090            "sink_0",
1091            crate::PadDirection::Sink,
1092            crate::PadPresence::Always,
1093            &caps,
1094        )
1095        .unwrap();
1096
1097        let target = crate::Pad::from_template(&templ);
1098        // Panic: attempt to build from a wildcard-named template
1099        //        with a target name missing a part
1100        //        without providing a name.
1101        let _ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_templ, &target)
1102            .unwrap()
1103            .build();
1104    }
1105
1106    #[test]
1107    #[should_panic]
1108    fn from_template_with_target_incompatible_conversion_unsigned() {
1109        crate::init().unwrap();
1110
1111        let caps = crate::Caps::new_any();
1112        let wildcard_templ = crate::PadTemplate::new(
1113            "sink_%u",
1114            crate::PadDirection::Sink,
1115            crate::PadPresence::Request,
1116            &caps,
1117        )
1118        .unwrap();
1119
1120        let templ = crate::PadTemplate::new(
1121            "sink_-1",
1122            crate::PadDirection::Sink,
1123            crate::PadPresence::Always,
1124            &caps,
1125        )
1126        .unwrap();
1127
1128        let target = crate::Pad::from_template(&templ);
1129        // Panic: attempt to build from a wildcard-named template
1130        //        with a target name %d, expecting %u
1131        //        without providing a name.
1132        let _ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_templ, &target)
1133            .unwrap()
1134            .build();
1135    }
1136
1137    #[test]
1138    #[should_panic]
1139    fn from_template_with_target_incompatible_conversion_decimal() {
1140        crate::init().unwrap();
1141
1142        let caps = crate::Caps::new_any();
1143        let wildcard_templ = crate::PadTemplate::new(
1144            "sink_%u",
1145            crate::PadDirection::Sink,
1146            crate::PadPresence::Request,
1147            &caps,
1148        )
1149        .unwrap();
1150
1151        let templ = crate::PadTemplate::new(
1152            "sink_test",
1153            crate::PadDirection::Sink,
1154            crate::PadPresence::Always,
1155            &caps,
1156        )
1157        .unwrap();
1158
1159        let target = crate::Pad::from_template(&templ);
1160        // Panic: attempt to build from a wildcard-named template
1161        //        with a target name with %s, expecting %d
1162        //        without providing a name.
1163        let _ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_templ, &target)
1164            .unwrap()
1165            .build();
1166    }
1167
1168    #[test]
1169    #[should_panic]
1170    fn from_template_with_target_incompatible_missing_decimal() {
1171        crate::init().unwrap();
1172
1173        let caps = crate::Caps::new_any();
1174        let wildcard_templ = crate::PadTemplate::new(
1175            "sink_%d",
1176            crate::PadDirection::Sink,
1177            crate::PadPresence::Request,
1178            &caps,
1179        )
1180        .unwrap();
1181
1182        let templ = crate::PadTemplate::new(
1183            "sink_",
1184            crate::PadDirection::Sink,
1185            crate::PadPresence::Always,
1186            &caps,
1187        )
1188        .unwrap();
1189
1190        let target = crate::Pad::from_template(&templ);
1191        // Panic: attempt to build from a wildcard-named template
1192        //        with a target name missing a number, expecting %d
1193        //        without providing a name.
1194        let _ghost_pad = GhostPad::builder_from_template_with_target(&wildcard_templ, &target)
1195            .unwrap()
1196            .build();
1197    }
1198}