Skip to main content

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