Skip to main content

gstreamer/
event.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{
4    borrow::Borrow, cmp, ffi::CStr, fmt, mem, num::NonZeroU32, ops::Deref, ops::DerefMut, ptr,
5};
6
7use glib::{translate::*, value::ToSendValue};
8
9use crate::{
10    ClockTime, EventType, ffi,
11    format::{
12        CompatibleFormattedValue, FormattedValue, FormattedValueIntrinsic, GenericFormattedValue,
13    },
14    structure::*,
15};
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub struct Seqnum(pub(crate) NonZeroU32);
19
20impl Seqnum {
21    #[doc(alias = "gst_util_seqnum_next")]
22    #[inline]
23    pub fn next() -> Self {
24        unsafe {
25            let v = ffi::gst_util_seqnum_next();
26            if v == 0 {
27                Seqnum::next()
28            } else {
29                Seqnum(NonZeroU32::new_unchecked(v))
30            }
31        }
32    }
33}
34
35impl IntoGlib for Seqnum {
36    type GlibType = u32;
37
38    #[inline]
39    fn into_glib(self) -> u32 {
40        self.0.get()
41    }
42}
43
44impl cmp::PartialOrd for Seqnum {
45    #[inline]
46    fn partial_cmp(&self, other: &Seqnum) -> Option<cmp::Ordering> {
47        Some(self.cmp(other))
48    }
49}
50
51impl cmp::Ord for Seqnum {
52    #[inline]
53    fn cmp(&self, other: &Seqnum) -> cmp::Ordering {
54        unsafe {
55            let ret = ffi::gst_util_seqnum_compare(self.0.get(), other.0.get());
56            ret.cmp(&0)
57        }
58    }
59}
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62pub struct GroupId(pub(crate) NonZeroU32);
63
64impl GroupId {
65    #[doc(alias = "gst_util_group_id_next")]
66    #[inline]
67    pub fn next() -> Self {
68        unsafe {
69            let v = ffi::gst_util_group_id_next();
70            if v == 0 {
71                GroupId::next()
72            } else {
73                GroupId(NonZeroU32::new_unchecked(v))
74            }
75        }
76    }
77}
78
79impl EventType {
80    #[doc(alias = "GST_EVENT_IS_UPSTREAM")]
81    #[inline]
82    pub fn is_upstream(self) -> bool {
83        (self.into_glib() as u32) & ffi::GST_EVENT_TYPE_UPSTREAM != 0
84    }
85
86    #[doc(alias = "GST_EVENT_IS_DOWNSTREAM")]
87    #[inline]
88    pub fn is_downstream(self) -> bool {
89        (self.into_glib() as u32) & ffi::GST_EVENT_TYPE_DOWNSTREAM != 0
90    }
91
92    #[doc(alias = "GST_EVENT_IS_SERIALIZED")]
93    #[inline]
94    pub fn is_serialized(self) -> bool {
95        (self.into_glib() as u32) & ffi::GST_EVENT_TYPE_SERIALIZED != 0
96    }
97
98    #[doc(alias = "GST_EVENT_IS_STICKY")]
99    #[inline]
100    pub fn is_sticky(self) -> bool {
101        (self.into_glib() as u32) & ffi::GST_EVENT_TYPE_STICKY != 0
102    }
103
104    #[doc(alias = "GST_EVENT_IS_STICKY_MULTI")]
105    #[inline]
106    pub fn is_sticky_multi(self) -> bool {
107        (self.into_glib() as u32) & ffi::GST_EVENT_TYPE_STICKY_MULTI != 0
108    }
109}
110
111impl PartialOrd for EventType {
112    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
113        if !self.is_serialized() || !other.is_serialized() {
114            return None;
115        }
116
117        // See gst_event_type_to_sticky_ordering() from 1.22
118        let fixup_event_ordering = |v| match v {
119            ffi::GST_EVENT_INSTANT_RATE_CHANGE => ffi::GST_EVENT_SEGMENT as u32 + 1,
120            _ => v as u32,
121        };
122
123        let v1 = fixup_event_ordering(self.into_glib());
124        let v2 = fixup_event_ordering(other.into_glib());
125
126        let stream_start = ffi::GST_EVENT_STREAM_START as u32;
127        let segment = ffi::GST_EVENT_SEGMENT as u32;
128        let eos = ffi::GST_EVENT_EOS as u32;
129
130        // Strictly ordered range between stream_start and segment,
131        // and EOS is bigger than everything else
132        if v1 >= stream_start && v1 <= segment || v2 >= stream_start && v2 <= segment {
133            Some(v1.cmp(&v2))
134        // If one is EOS, the other is definitely less or equal
135        } else if v1 == eos || v2 == eos {
136            if v1 == v2 {
137                Some(cmp::Ordering::Equal)
138            } else if v1 == eos {
139                Some(cmp::Ordering::Greater)
140            } else {
141                Some(cmp::Ordering::Less)
142            }
143        } else {
144            None
145        }
146    }
147}
148
149mini_object_wrapper!(Event, EventRef, ffi::GstEvent, || {
150    ffi::gst_event_get_type()
151});
152
153impl EventRef {
154    #[doc(alias = "get_seqnum")]
155    #[doc(alias = "gst_event_get_seqnum")]
156    pub fn seqnum(&self) -> Seqnum {
157        unsafe {
158            let seqnum = ffi::gst_event_get_seqnum(self.as_mut_ptr());
159            debug_assert_ne!(seqnum, 0);
160            Seqnum(NonZeroU32::new_unchecked(seqnum))
161        }
162    }
163
164    #[doc(alias = "gst_event_set_seqnum")]
165    pub fn set_seqnum(&mut self, seqnum: Seqnum) {
166        unsafe {
167            ffi::gst_event_set_seqnum(self.as_mut_ptr(), seqnum.0.get());
168        }
169    }
170
171    #[doc(alias = "get_running_time_offset")]
172    #[doc(alias = "gst_event_get_running_time_offset")]
173    pub fn running_time_offset(&self) -> i64 {
174        unsafe { ffi::gst_event_get_running_time_offset(self.as_mut_ptr()) }
175    }
176
177    #[doc(alias = "gst_event_set_running_time_offset")]
178    pub fn set_running_time_offset(&mut self, offset: i64) {
179        unsafe { ffi::gst_event_set_running_time_offset(self.as_mut_ptr(), offset) }
180    }
181
182    #[doc(alias = "get_structure")]
183    #[doc(alias = "gst_event_get_structure")]
184    #[inline]
185    pub fn structure(&self) -> Option<&StructureRef> {
186        unsafe {
187            let structure = ffi::gst_event_get_structure(self.as_mut_ptr());
188            if structure.is_null() {
189                None
190            } else {
191                Some(StructureRef::from_glib_borrow(structure))
192            }
193        }
194    }
195
196    #[doc(alias = "gst_event_writable_structure")]
197    #[inline]
198    pub fn structure_mut(&mut self) -> &mut StructureRef {
199        unsafe {
200            StructureRef::from_glib_borrow_mut(ffi::gst_event_writable_structure(self.as_mut_ptr()))
201        }
202    }
203
204    #[doc(alias = "GST_EVENT_IS_UPSTREAM")]
205    #[inline]
206    pub fn is_upstream(&self) -> bool {
207        self.type_().is_upstream()
208    }
209
210    #[doc(alias = "GST_EVENT_IS_DOWNSTREAM")]
211    #[inline]
212    pub fn is_downstream(&self) -> bool {
213        self.type_().is_downstream()
214    }
215
216    #[doc(alias = "GST_EVENT_IS_SERIALIZED")]
217    #[inline]
218    pub fn is_serialized(&self) -> bool {
219        self.type_().is_serialized()
220    }
221
222    #[doc(alias = "GST_EVENT_IS_STICKY")]
223    #[inline]
224    pub fn is_sticky(&self) -> bool {
225        self.type_().is_sticky()
226    }
227
228    #[doc(alias = "GST_EVENT_IS_STICKY_MULTI")]
229    #[inline]
230    pub fn is_sticky_multi(&self) -> bool {
231        self.type_().is_sticky_multi()
232    }
233
234    #[doc(alias = "get_type")]
235    #[doc(alias = "GST_EVENT_TYPE")]
236    #[inline]
237    pub fn type_(&self) -> EventType {
238        unsafe { from_glib((*self.as_ptr()).type_) }
239    }
240
241    #[doc(alias = "gst_event_has_name")]
242    #[inline]
243    pub fn has_name(&self, name: &str) -> bool {
244        self.structure().is_some_and(|s| s.has_name(name))
245    }
246
247    pub fn view(&self) -> EventView<'_> {
248        unsafe {
249            let type_ = (*self.as_ptr()).type_;
250
251            match type_ {
252                ffi::GST_EVENT_FLUSH_START => FlushStart::view(self),
253                ffi::GST_EVENT_FLUSH_STOP => FlushStop::view(self),
254                ffi::GST_EVENT_STREAM_START => StreamStart::view(self),
255                ffi::GST_EVENT_CAPS => Caps::view(self),
256                ffi::GST_EVENT_SEGMENT => Segment::view(self),
257                ffi::GST_EVENT_STREAM_COLLECTION => StreamCollection::view(self),
258                ffi::GST_EVENT_TAG => Tag::view(self),
259                ffi::GST_EVENT_BUFFERSIZE => Buffersize::view(self),
260                ffi::GST_EVENT_SINK_MESSAGE => SinkMessage::view(self),
261                ffi::GST_EVENT_STREAM_GROUP_DONE => StreamGroupDone::view(self),
262                ffi::GST_EVENT_EOS => Eos::view(self),
263                ffi::GST_EVENT_TOC => Toc::view(self),
264                ffi::GST_EVENT_PROTECTION => Protection::view(self),
265                ffi::GST_EVENT_SEGMENT_DONE => SegmentDone::view(self),
266                ffi::GST_EVENT_GAP => Gap::view(self),
267                #[cfg(feature = "v1_18")]
268                ffi::GST_EVENT_INSTANT_RATE_CHANGE => InstantRateChange::view(self),
269                ffi::GST_EVENT_QOS => Qos::view(self),
270                ffi::GST_EVENT_SEEK => Seek::view(self),
271                ffi::GST_EVENT_NAVIGATION => Navigation::view(self),
272                ffi::GST_EVENT_LATENCY => Latency::view(self),
273                ffi::GST_EVENT_STEP => Step::view(self),
274                ffi::GST_EVENT_RECONFIGURE => Reconfigure::view(self),
275                ffi::GST_EVENT_TOC_SELECT => TocSelect::view(self),
276                ffi::GST_EVENT_SELECT_STREAMS => SelectStreams::view(self),
277                #[cfg(feature = "v1_18")]
278                ffi::GST_EVENT_INSTANT_RATE_SYNC_TIME => InstantRateSyncTime::view(self),
279                ffi::GST_EVENT_CUSTOM_UPSTREAM => CustomUpstream::view(self),
280                ffi::GST_EVENT_CUSTOM_DOWNSTREAM => CustomDownstream::view(self),
281                ffi::GST_EVENT_CUSTOM_DOWNSTREAM_OOB => CustomDownstreamOob::view(self),
282                ffi::GST_EVENT_CUSTOM_DOWNSTREAM_STICKY => CustomDownstreamSticky::view(self),
283                ffi::GST_EVENT_CUSTOM_BOTH => CustomBoth::view(self),
284                ffi::GST_EVENT_CUSTOM_BOTH_OOB => CustomBothOob::view(self),
285                _ => Other::view(self),
286            }
287        }
288    }
289
290    pub fn view_mut(&mut self) -> EventViewMut<'_> {
291        unsafe {
292            let type_ = (*self.as_ptr()).type_;
293
294            match type_ {
295                ffi::GST_EVENT_FLUSH_START => FlushStart::view_mut(self),
296                ffi::GST_EVENT_FLUSH_STOP => FlushStop::view_mut(self),
297                ffi::GST_EVENT_STREAM_START => StreamStart::view_mut(self),
298                ffi::GST_EVENT_CAPS => Caps::view_mut(self),
299                ffi::GST_EVENT_SEGMENT => Segment::view_mut(self),
300                ffi::GST_EVENT_STREAM_COLLECTION => StreamCollection::view_mut(self),
301                ffi::GST_EVENT_TAG => Tag::view_mut(self),
302                ffi::GST_EVENT_BUFFERSIZE => Buffersize::view_mut(self),
303                ffi::GST_EVENT_SINK_MESSAGE => SinkMessage::view_mut(self),
304                ffi::GST_EVENT_STREAM_GROUP_DONE => StreamGroupDone::view_mut(self),
305                ffi::GST_EVENT_EOS => Eos::view_mut(self),
306                ffi::GST_EVENT_TOC => Toc::view_mut(self),
307                ffi::GST_EVENT_PROTECTION => Protection::view_mut(self),
308                ffi::GST_EVENT_SEGMENT_DONE => SegmentDone::view_mut(self),
309                ffi::GST_EVENT_GAP => Gap::view_mut(self),
310                #[cfg(feature = "v1_18")]
311                ffi::GST_EVENT_INSTANT_RATE_CHANGE => InstantRateChange::view_mut(self),
312                ffi::GST_EVENT_QOS => Qos::view_mut(self),
313                ffi::GST_EVENT_SEEK => Seek::view_mut(self),
314                ffi::GST_EVENT_NAVIGATION => Navigation::view_mut(self),
315                ffi::GST_EVENT_LATENCY => Latency::view_mut(self),
316                ffi::GST_EVENT_STEP => Step::view_mut(self),
317                ffi::GST_EVENT_RECONFIGURE => Reconfigure::view_mut(self),
318                ffi::GST_EVENT_TOC_SELECT => TocSelect::view_mut(self),
319                ffi::GST_EVENT_SELECT_STREAMS => SelectStreams::view_mut(self),
320                #[cfg(feature = "v1_18")]
321                ffi::GST_EVENT_INSTANT_RATE_SYNC_TIME => InstantRateSyncTime::view_mut(self),
322                ffi::GST_EVENT_CUSTOM_UPSTREAM => CustomUpstream::view_mut(self),
323                ffi::GST_EVENT_CUSTOM_DOWNSTREAM => CustomDownstream::view_mut(self),
324                ffi::GST_EVENT_CUSTOM_DOWNSTREAM_OOB => CustomDownstreamOob::view_mut(self),
325                ffi::GST_EVENT_CUSTOM_DOWNSTREAM_STICKY => CustomDownstreamSticky::view_mut(self),
326                ffi::GST_EVENT_CUSTOM_BOTH => CustomBoth::view_mut(self),
327                ffi::GST_EVENT_CUSTOM_BOTH_OOB => CustomBothOob::view_mut(self),
328                _ => Other::view_mut(self),
329            }
330        }
331    }
332}
333
334impl fmt::Debug for Event {
335    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
336        EventRef::fmt(self, f)
337    }
338}
339
340impl fmt::Debug for EventRef {
341    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
342        let concrete: &dyn fmt::Debug = match self.view() {
343            EventView::FlushStart(concrete) => concrete,
344            EventView::FlushStop(concrete) => concrete,
345            EventView::StreamStart(concrete) => concrete,
346            EventView::Caps(concrete) => concrete,
347            EventView::Segment(concrete) => concrete,
348            EventView::StreamCollection(concrete) => concrete,
349            EventView::Tag(concrete) => concrete,
350            EventView::Buffersize(concrete) => concrete,
351            EventView::SinkMessage(concrete) => concrete,
352            EventView::StreamGroupDone(concrete) => concrete,
353            EventView::Eos(concrete) => concrete,
354            EventView::Toc(concrete) => concrete,
355            EventView::Protection(concrete) => concrete,
356            EventView::SegmentDone(concrete) => concrete,
357            EventView::Gap(concrete) => concrete,
358            #[cfg(feature = "v1_18")]
359            EventView::InstantRateChange(concrete) => concrete,
360            EventView::Qos(concrete) => concrete,
361            EventView::Seek(concrete) => concrete,
362            EventView::Navigation(concrete) => concrete,
363            EventView::Latency(concrete) => concrete,
364            EventView::Step(concrete) => concrete,
365            EventView::Reconfigure(concrete) => concrete,
366            EventView::TocSelect(concrete) => concrete,
367            EventView::SelectStreams(concrete) => concrete,
368            #[cfg(feature = "v1_18")]
369            EventView::InstantRateSyncTime(concrete) => concrete,
370            EventView::CustomUpstream(concrete) => concrete,
371            EventView::CustomDownstream(concrete) => concrete,
372            EventView::CustomDownstreamOob(concrete) => concrete,
373            EventView::CustomDownstreamSticky(concrete) => concrete,
374            EventView::CustomBoth(concrete) => concrete,
375            EventView::CustomBothOob(concrete) => concrete,
376            EventView::Other(concrete) => concrete,
377        };
378
379        concrete.fmt(f)
380    }
381}
382
383pub trait StickyEventType: ToOwned {
384    const TYPE: EventType;
385
386    unsafe fn from_event(event: Event) -> Self::Owned;
387}
388
389#[derive(Debug)]
390#[non_exhaustive]
391pub enum EventView<'a> {
392    FlushStart(&'a FlushStart),
393    FlushStop(&'a FlushStop),
394    StreamStart(&'a StreamStart),
395    Caps(&'a Caps),
396    Segment(&'a Segment),
397    StreamCollection(&'a StreamCollection),
398    Tag(&'a Tag),
399    Buffersize(&'a Buffersize),
400    SinkMessage(&'a SinkMessage),
401    StreamGroupDone(&'a StreamGroupDone),
402    Eos(&'a Eos),
403    Toc(&'a Toc),
404    Protection(&'a Protection),
405    SegmentDone(&'a SegmentDone),
406    Gap(&'a Gap),
407    #[cfg(feature = "v1_18")]
408    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
409    InstantRateChange(&'a InstantRateChange),
410    Qos(&'a Qos),
411    Seek(&'a Seek),
412    Navigation(&'a Navigation),
413    Latency(&'a Latency),
414    Step(&'a Step),
415    Reconfigure(&'a Reconfigure),
416    TocSelect(&'a TocSelect),
417    SelectStreams(&'a SelectStreams),
418    #[cfg(feature = "v1_18")]
419    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
420    InstantRateSyncTime(&'a InstantRateSyncTime),
421    CustomUpstream(&'a CustomUpstream),
422    CustomDownstream(&'a CustomDownstream),
423    CustomDownstreamOob(&'a CustomDownstreamOob),
424    CustomDownstreamSticky(&'a CustomDownstreamSticky),
425    CustomBoth(&'a CustomBoth),
426    CustomBothOob(&'a CustomBothOob),
427    Other(&'a Other),
428}
429
430#[derive(Debug)]
431#[non_exhaustive]
432pub enum EventViewMut<'a> {
433    FlushStart(&'a mut FlushStart),
434    FlushStop(&'a mut FlushStop),
435    StreamStart(&'a mut StreamStart),
436    Caps(&'a mut Caps),
437    Segment(&'a mut Segment),
438    StreamCollection(&'a mut StreamCollection),
439    Tag(&'a mut Tag),
440    Buffersize(&'a mut Buffersize),
441    SinkMessage(&'a mut SinkMessage),
442    StreamGroupDone(&'a mut StreamGroupDone),
443    Eos(&'a mut Eos),
444    Toc(&'a mut Toc),
445    Protection(&'a mut Protection),
446    SegmentDone(&'a mut SegmentDone),
447    Gap(&'a mut Gap),
448    #[cfg(feature = "v1_18")]
449    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
450    InstantRateChange(&'a mut InstantRateChange),
451    Qos(&'a mut Qos),
452    Seek(&'a mut Seek),
453    Navigation(&'a mut Navigation),
454    Latency(&'a mut Latency),
455    Step(&'a mut Step),
456    Reconfigure(&'a mut Reconfigure),
457    TocSelect(&'a mut TocSelect),
458    SelectStreams(&'a mut SelectStreams),
459    #[cfg(feature = "v1_18")]
460    #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
461    InstantRateSyncTime(&'a mut InstantRateSyncTime),
462    CustomUpstream(&'a mut CustomUpstream),
463    CustomDownstream(&'a mut CustomDownstream),
464    CustomDownstreamOob(&'a mut CustomDownstreamOob),
465    CustomDownstreamSticky(&'a mut CustomDownstreamSticky),
466    CustomBoth(&'a mut CustomBoth),
467    CustomBothOob(&'a mut CustomBothOob),
468    Other(&'a mut Other),
469}
470
471macro_rules! declare_concrete_event {
472    (@sticky $name:ident, $param:ident) => {
473        declare_concrete_event!($name, $param);
474
475        impl StickyEventType for $name {
476            const TYPE: EventType = EventType::$name;
477
478            #[inline]
479            unsafe fn from_event(event: Event) -> Self::Owned {
480                $name::<Event>(event)
481            }
482        }
483    };
484    ($name:ident, $param:ident) => {
485        #[repr(transparent)]
486        pub struct $name<$param = EventRef>($param);
487
488        impl $name {
489            #[inline]
490            pub fn event(&self) -> &EventRef {
491                unsafe { &*(self as *const Self as *const EventRef) }
492            }
493
494            #[inline]
495            pub fn event_mut(&mut self) -> &mut EventRef {
496                unsafe { &mut *(self as *mut Self as *mut EventRef) }
497            }
498
499            #[inline]
500            unsafe fn view(event: &EventRef) -> EventView<'_> {
501                unsafe {
502                    let event = &*(event as *const EventRef as *const Self);
503                    EventView::$name(event)
504                }
505            }
506
507            #[inline]
508            unsafe fn view_mut(event: &mut EventRef) -> EventViewMut<'_> {
509                unsafe {
510                    let event = &mut *(event as *mut EventRef as *mut Self);
511                    EventViewMut::$name(event)
512                }
513            }
514        }
515
516        impl Deref for $name {
517            type Target = EventRef;
518
519            #[inline]
520            fn deref(&self) -> &Self::Target {
521                self.event()
522            }
523        }
524
525        impl DerefMut for $name {
526            #[inline]
527            fn deref_mut(&mut self) -> &mut Self::Target {
528                self.event_mut()
529            }
530        }
531
532        impl ToOwned for $name {
533            type Owned = $name<Event>;
534
535            #[inline]
536            fn to_owned(&self) -> Self::Owned {
537                $name::<Event>(self.copy())
538            }
539        }
540
541        impl $name<Event> {
542            #[inline]
543            pub fn get_mut(&mut self) -> Option<&mut $name> {
544                self.0
545                    .get_mut()
546                    .map(|event| unsafe { &mut *(event as *mut EventRef as *mut $name) })
547            }
548        }
549
550        impl Deref for $name<Event> {
551            type Target = $name;
552
553            #[inline]
554            fn deref(&self) -> &Self::Target {
555                unsafe { &*(self.0.as_ptr() as *const Self::Target) }
556            }
557        }
558
559        impl DerefMut for $name<Event> {
560            #[inline]
561            fn deref_mut(&mut self) -> &mut Self::Target {
562                debug_assert!(self.0.is_writable());
563                unsafe { &mut *(self.0.as_mut_ptr() as *mut Self::Target) }
564            }
565        }
566
567        impl Borrow<$name> for $name<Event> {
568            #[inline]
569            fn borrow(&self) -> &$name {
570                &*self
571            }
572        }
573
574        impl From<$name<Event>> for Event {
575            #[inline]
576            fn from(concrete: $name<Event>) -> Self {
577                skip_assert_initialized!();
578                concrete.0
579            }
580        }
581    };
582}
583
584/// Implements `Debug::fmt` for the concrete `Event` `$name`.
585///
586/// This implementation displays the generic `Event` attributes and adds
587/// specific concrete attributes declared by the caller with `$field: $accessor`.
588///
589/// The `reserved_fields` array indicates the name of the fields which are reserved
590/// for the concrete `Event`. This is used by the macro to distinguish fields which
591/// are handled by a Rust accessor (displayed first) from user-defined fields
592/// (displayed last). The names in the `reserved_fields` array must match the names
593/// as they appear in the internal `Structure`, which may be different from the
594/// name used by the Rust accessor or the `debug` field name.
595///
596/// ## Examples
597///
598/// The `SegmentDone` `Event` debug definition not only lists the `position` field,
599/// but also the `format` field because they are both part of the `Event`. The Rust
600/// bindings returns the `position` as a `GenericFormattedValue` which embeds the
601/// value and its format.
602///
603/// ```ignore
604/// impl_debug_concrete_event!(SegmentDone {
605///     reserved_fields: ["format", "position"],
606///     "position": position,
607/// });
608///
609/// ```
610///
611/// A field might only be available starting from a particular version.
612///
613/// ```ignore
614/// impl_debug_concrete_event!(Gap {
615///     reserved_fields: [
616///         "timestamp", "duration"
617///         #[cfg(feature = "v1_20")]
618///         "gap-flags",
619///     ],
620///     "timestamp": timestamp,
621///     "duration": duration,
622///     #[cfg(feature = "v1_20")]
623///     "flags": gap_flags,
624/// });
625/// ```
626///
627/// In the above example:
628///
629/// * if feature `v1_20` is used, `gap-flags` will be expected and displayed as `flags`.
630/// * if feature `v1_20` is not used, `gap-flags` will not be expected. However, if it
631///   is present in the `Event`, it will be displayed as a user-defined field.
632macro_rules! impl_debug_concrete_event {
633    (
634        $name:ident $({
635            reserved_fields: $reserved_fields:expr,
636            $(
637                $( #[$att:meta] )?
638                $field:literal $( : $accessor:ident )? $(,)?
639            )+
640        })?
641    ) => {
642        impl std::fmt::Debug for $name {
643            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
644                let mut ds = f.debug_struct("Event");
645                #[allow(unused_mut)]
646                let mut ds = ds
647                    .field("ptr", &self.as_ptr())
648                    .field("type", &self.type_())
649                    .field("seqnum", &self.event().seqnum())
650                    .field("running-time-offset", &self.event().running_time_offset());
651
652                #[allow(unused)]
653                let mut reserved_fields = [].as_slice();
654                $(
655                    reserved_fields = ($reserved_fields).as_slice();
656                    $(
657                        $( #[$att] )?
658                        {
659                            $( ds = ds.field($field, &self.$accessor()); )?
660                        }
661                    )+
662                )?
663
664                // only display user-defined fields
665                if let Some(ref structure) = self.structure() {
666                    for (field, value) in structure.iter()
667                        .filter(|(field, _value)| !reserved_fields.contains(&field.as_str()))
668                    {
669                        ds = ds.field(field, value);
670                    }
671                }
672
673                ds.finish()
674            }
675        }
676
677        impl std::fmt::Debug for $name<Event> {
678            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
679                $name::<EventRef>::fmt(self, f)
680            }
681        }
682    };
683}
684
685declare_concrete_event!(FlushStart, T);
686impl FlushStart<Event> {
687    #[doc(alias = "gst_event_new_flush_start")]
688    #[allow(clippy::new_ret_no_self)]
689    pub fn new() -> Event {
690        skip_assert_initialized!();
691        Self::builder().build()
692    }
693
694    pub fn builder<'a>() -> FlushStartBuilder<'a> {
695        assert_initialized_main_thread!();
696        FlushStartBuilder::new()
697    }
698}
699
700impl_debug_concrete_event!(FlushStart);
701
702declare_concrete_event!(FlushStop, T);
703impl FlushStop<Event> {
704    #[doc(alias = "gst_event_new_flush_stop")]
705    #[allow(clippy::new_ret_no_self)]
706    pub fn new(reset_time: bool) -> Event {
707        skip_assert_initialized!();
708        Self::builder(reset_time).build()
709    }
710
711    pub fn builder<'a>(reset_time: bool) -> FlushStopBuilder<'a> {
712        assert_initialized_main_thread!();
713        FlushStopBuilder::new(reset_time)
714    }
715}
716
717impl FlushStop {
718    #[doc(alias = "get_reset_time")]
719    #[doc(alias = "gst_event_parse_flush_stop")]
720    pub fn resets_time(&self) -> bool {
721        unsafe {
722            let mut reset_time = mem::MaybeUninit::uninit();
723
724            ffi::gst_event_parse_flush_stop(self.as_mut_ptr(), reset_time.as_mut_ptr());
725
726            from_glib(reset_time.assume_init())
727        }
728    }
729}
730
731impl_debug_concrete_event!(FlushStop {
732    reserved_fields: ["reset-time"],
733    "resets-time": resets_time,
734});
735
736declare_concrete_event!(@sticky StreamStart, T);
737impl StreamStart<Event> {
738    #[doc(alias = "gst_event_new_stream_start")]
739    #[allow(clippy::new_ret_no_self)]
740    pub fn new(stream_id: &str) -> Event {
741        skip_assert_initialized!();
742        Self::builder(stream_id).build()
743    }
744
745    pub fn builder(stream_id: &str) -> StreamStartBuilder<'_> {
746        assert_initialized_main_thread!();
747        StreamStartBuilder::new(stream_id)
748    }
749}
750
751impl StreamStart {
752    #[doc(alias = "get_stream_id")]
753    #[doc(alias = "gst_event_parse_stream_start")]
754    pub fn stream_id(&self) -> &str {
755        unsafe {
756            let mut stream_id = ptr::null();
757
758            ffi::gst_event_parse_stream_start(self.as_mut_ptr(), &mut stream_id);
759            CStr::from_ptr(stream_id).to_str().unwrap()
760        }
761    }
762
763    #[doc(alias = "get_stream_flags")]
764    #[doc(alias = "gst_event_parse_stream_flags")]
765    pub fn stream_flags(&self) -> crate::StreamFlags {
766        unsafe {
767            let mut stream_flags = mem::MaybeUninit::uninit();
768
769            ffi::gst_event_parse_stream_flags(self.as_mut_ptr(), stream_flags.as_mut_ptr());
770
771            from_glib(stream_flags.assume_init())
772        }
773    }
774
775    #[doc(alias = "get_group_id")]
776    #[doc(alias = "gst_event_parse_group_id")]
777    pub fn group_id(&self) -> Option<GroupId> {
778        unsafe {
779            let mut group_id = mem::MaybeUninit::uninit();
780
781            ffi::gst_event_parse_group_id(self.as_mut_ptr(), group_id.as_mut_ptr());
782
783            let group_id = group_id.assume_init();
784            if group_id == 0 {
785                None
786            } else {
787                Some(GroupId(NonZeroU32::new_unchecked(group_id)))
788            }
789        }
790    }
791
792    #[doc(alias = "gst_event_set_group_id")]
793    pub fn set_group_id(&mut self, group_id: GroupId) {
794        unsafe {
795            ffi::gst_event_set_group_id(self.as_mut_ptr(), group_id.0.get());
796        }
797    }
798
799    #[doc(alias = "get_stream")]
800    #[doc(alias = "gst_event_parse_stream")]
801    pub fn stream(&self) -> Option<crate::Stream> {
802        unsafe {
803            let mut stream = ptr::null_mut();
804            ffi::gst_event_parse_stream(self.as_mut_ptr(), &mut stream);
805            from_glib_full(stream)
806        }
807    }
808}
809
810impl_debug_concrete_event!(StreamStart {
811    reserved_fields: ["stream-id", "flags", "stream", "group-id"],
812    "stream-id": stream_id,
813    "stream-flags": stream_flags,
814    "group-id": group_id,
815    "stream": stream,
816});
817
818declare_concrete_event!(@sticky Caps, T);
819impl Caps<Event> {
820    #[doc(alias = "gst_event_new_caps")]
821    #[allow(clippy::new_ret_no_self)]
822    pub fn new(caps: &crate::Caps) -> Event {
823        skip_assert_initialized!();
824        Self::builder(caps).build()
825    }
826
827    pub fn builder(caps: &crate::Caps) -> CapsBuilder<'_> {
828        assert_initialized_main_thread!();
829        CapsBuilder::new(caps)
830    }
831}
832
833impl Caps {
834    #[doc(alias = "get_caps")]
835    #[doc(alias = "gst_event_parse_caps")]
836    pub fn caps(&self) -> &crate::CapsRef {
837        unsafe {
838            let mut caps = ptr::null_mut();
839
840            ffi::gst_event_parse_caps(self.as_mut_ptr(), &mut caps);
841            crate::CapsRef::from_ptr(caps)
842        }
843    }
844
845    #[doc(alias = "get_caps_owned")]
846    #[doc(alias = "gst_event_parse_caps")]
847    pub fn caps_owned(&self) -> crate::Caps {
848        unsafe { from_glib_none(self.caps().as_ptr()) }
849    }
850}
851
852impl_debug_concrete_event!(Caps {
853    reserved_fields: ["caps"],
854    "caps": caps,
855});
856
857declare_concrete_event!(@sticky Segment, T);
858impl Segment<Event> {
859    #[doc(alias = "gst_event_new_segment")]
860    #[allow(clippy::new_ret_no_self)]
861    pub fn new<F: FormattedValueIntrinsic>(segment: &crate::FormattedSegment<F>) -> Event {
862        skip_assert_initialized!();
863        Self::builder(segment).build()
864    }
865
866    pub fn builder<F: FormattedValueIntrinsic>(
867        segment: &crate::FormattedSegment<F>,
868    ) -> SegmentBuilder<'_> {
869        assert_initialized_main_thread!();
870        SegmentBuilder::new(segment.as_ref())
871    }
872}
873
874impl Segment {
875    #[doc(alias = "get_segment")]
876    #[doc(alias = "gst_event_parse_segment")]
877    pub fn segment(&self) -> &crate::Segment {
878        unsafe {
879            let mut segment = ptr::null();
880
881            ffi::gst_event_parse_segment(self.as_mut_ptr(), &mut segment);
882            &*(segment as *mut ffi::GstSegment as *mut crate::Segment)
883        }
884    }
885}
886
887impl_debug_concrete_event!(Segment {
888    reserved_fields: ["segment"],
889    "segment": segment,
890});
891
892declare_concrete_event!(@sticky StreamCollection, T);
893impl StreamCollection<Event> {
894    #[doc(alias = "gst_event_new_stream_collection")]
895    #[allow(clippy::new_ret_no_self)]
896    pub fn new(stream_collection: &crate::StreamCollection) -> Event {
897        skip_assert_initialized!();
898        Self::builder(stream_collection).build()
899    }
900
901    pub fn builder(stream_collection: &crate::StreamCollection) -> StreamCollectionBuilder<'_> {
902        assert_initialized_main_thread!();
903        StreamCollectionBuilder::new(stream_collection)
904    }
905}
906
907impl StreamCollection {
908    #[doc(alias = "get_stream_collection")]
909    #[doc(alias = "gst_event_parse_stream_collection")]
910    pub fn stream_collection(&self) -> crate::StreamCollection {
911        unsafe {
912            let mut stream_collection = ptr::null_mut();
913
914            ffi::gst_event_parse_stream_collection(self.as_mut_ptr(), &mut stream_collection);
915            from_glib_full(stream_collection)
916        }
917    }
918}
919
920impl_debug_concrete_event!(StreamCollection {
921    reserved_fields: ["collection"],
922    "collection": stream_collection,
923});
924
925declare_concrete_event!(@sticky Tag, T);
926impl Tag<Event> {
927    #[doc(alias = "gst_event_new_tag")]
928    #[allow(clippy::new_ret_no_self)]
929    pub fn new(tags: crate::TagList) -> Event {
930        skip_assert_initialized!();
931        Self::builder(tags).build()
932    }
933
934    pub fn builder<'a>(tags: crate::TagList) -> TagBuilder<'a> {
935        assert_initialized_main_thread!();
936        TagBuilder::new(tags)
937    }
938}
939
940impl Tag {
941    #[doc(alias = "get_tag")]
942    #[doc(alias = "gst_event_parse_tag")]
943    pub fn tag(&self) -> &crate::TagListRef {
944        unsafe {
945            let mut tags = ptr::null_mut();
946
947            ffi::gst_event_parse_tag(self.as_mut_ptr(), &mut tags);
948            crate::TagListRef::from_ptr(tags)
949        }
950    }
951
952    #[doc(alias = "get_tag_owned")]
953    #[doc(alias = "gst_event_parse_tag")]
954    pub fn tag_owned(&self) -> crate::TagList {
955        unsafe { from_glib_none(self.tag().as_ptr()) }
956    }
957}
958
959impl_debug_concrete_event!(Tag {
960    reserved_fields: ["taglist"],
961    "tag": tag,
962});
963
964declare_concrete_event!(@sticky Buffersize, T);
965impl Buffersize<Event> {
966    #[doc(alias = "gst_event_new_buffer_size")]
967    #[allow(clippy::new_ret_no_self)]
968    pub fn new<V: FormattedValue>(
969        minsize: V,
970        maxsize: impl CompatibleFormattedValue<V>,
971        r#async: bool,
972    ) -> Event {
973        skip_assert_initialized!();
974        Self::builder(minsize, maxsize, r#async).build()
975    }
976
977    pub fn builder<'a, V: FormattedValue>(
978        minsize: V,
979        maxsize: impl CompatibleFormattedValue<V>,
980        r#async: bool,
981    ) -> BuffersizeBuilder<'a> {
982        assert_initialized_main_thread!();
983        let maxsize = maxsize.try_into_checked(minsize).unwrap();
984
985        BuffersizeBuilder::new(minsize.into(), maxsize.into(), r#async)
986    }
987}
988
989impl Buffersize {
990    #[doc(alias = "gst_event_parse_buffer_size")]
991    pub fn get(&self) -> (GenericFormattedValue, GenericFormattedValue, bool) {
992        unsafe {
993            let mut fmt = mem::MaybeUninit::uninit();
994            let mut minsize = mem::MaybeUninit::uninit();
995            let mut maxsize = mem::MaybeUninit::uninit();
996            let mut async_ = mem::MaybeUninit::uninit();
997
998            ffi::gst_event_parse_buffer_size(
999                self.as_mut_ptr(),
1000                fmt.as_mut_ptr(),
1001                minsize.as_mut_ptr(),
1002                maxsize.as_mut_ptr(),
1003                async_.as_mut_ptr(),
1004            );
1005            (
1006                GenericFormattedValue::new(from_glib(fmt.assume_init()), minsize.assume_init()),
1007                GenericFormattedValue::new(from_glib(fmt.assume_init()), maxsize.assume_init()),
1008                from_glib(async_.assume_init()),
1009            )
1010        }
1011    }
1012
1013    #[doc(alias = "gst_event_parse_buffer_size")]
1014    pub fn min_size(&self) -> GenericFormattedValue {
1015        self.get().0
1016    }
1017
1018    #[doc(alias = "gst_event_parse_buffer_size")]
1019    pub fn max_size(&self) -> GenericFormattedValue {
1020        self.get().1
1021    }
1022
1023    #[doc(alias = "gst_event_parse_buffer_size")]
1024    pub fn async_(&self) -> bool {
1025        self.get().2
1026    }
1027}
1028
1029impl_debug_concrete_event!(Buffersize {
1030    reserved_fields: ["format", "minsize", "maxsize", "async"],
1031    "min-size": min_size,
1032    "max-size": max_size,
1033    "async": async_,
1034});
1035
1036declare_concrete_event!(@sticky SinkMessage, T);
1037impl SinkMessage<Event> {
1038    #[doc(alias = "gst_event_new_sink_message")]
1039    #[allow(clippy::new_ret_no_self)]
1040    pub fn new(name: &str, msg: &crate::Message) -> Event {
1041        skip_assert_initialized!();
1042        Self::builder(name, msg).build()
1043    }
1044
1045    pub fn builder<'a>(name: &'a str, msg: &'a crate::Message) -> SinkMessageBuilder<'a> {
1046        assert_initialized_main_thread!();
1047        SinkMessageBuilder::new(name, msg)
1048    }
1049}
1050
1051impl SinkMessage {
1052    #[doc(alias = "get_message")]
1053    #[doc(alias = "gst_event_parse_sink_message")]
1054    pub fn message(&self) -> crate::Message {
1055        unsafe {
1056            let mut msg = ptr::null_mut();
1057
1058            ffi::gst_event_parse_sink_message(self.as_mut_ptr(), &mut msg);
1059            from_glib_full(msg)
1060        }
1061    }
1062}
1063
1064impl_debug_concrete_event!(SinkMessage {
1065    reserved_fields: ["message"],
1066    "message": message,
1067});
1068
1069declare_concrete_event!(@sticky StreamGroupDone, T);
1070impl StreamGroupDone<Event> {
1071    #[doc(alias = "gst_event_new_stream_group_done")]
1072    #[allow(clippy::new_ret_no_self)]
1073    pub fn new(group_id: GroupId) -> Event {
1074        skip_assert_initialized!();
1075        Self::builder(group_id).build()
1076    }
1077
1078    pub fn builder<'a>(group_id: GroupId) -> StreamGroupDoneBuilder<'a> {
1079        assert_initialized_main_thread!();
1080        StreamGroupDoneBuilder::new(group_id)
1081    }
1082}
1083
1084impl StreamGroupDone {
1085    #[doc(alias = "get_group_id")]
1086    #[doc(alias = "gst_event_parse_stream_group_done")]
1087    pub fn group_id(&self) -> GroupId {
1088        unsafe {
1089            let mut group_id = mem::MaybeUninit::uninit();
1090
1091            ffi::gst_event_parse_stream_group_done(self.as_mut_ptr(), group_id.as_mut_ptr());
1092
1093            let group_id = group_id.assume_init();
1094            debug_assert_ne!(group_id, 0);
1095            GroupId(NonZeroU32::new_unchecked(group_id))
1096        }
1097    }
1098}
1099
1100impl_debug_concrete_event!(StreamGroupDone {
1101    reserved_fields: ["group-id"],
1102    "group-id": group_id,
1103});
1104
1105declare_concrete_event!(@sticky Eos, T);
1106impl Eos<Event> {
1107    #[doc(alias = "gst_event_new_eos")]
1108    #[allow(clippy::new_ret_no_self)]
1109    pub fn new() -> Event {
1110        skip_assert_initialized!();
1111        Self::builder().build()
1112    }
1113
1114    pub fn builder<'a>() -> EosBuilder<'a> {
1115        assert_initialized_main_thread!();
1116        EosBuilder::new()
1117    }
1118}
1119
1120impl_debug_concrete_event!(Eos);
1121
1122declare_concrete_event!(@sticky Toc, T);
1123impl Toc<Event> {
1124    // FIXME could use false for updated as default
1125    // Even better: use an enum for updated so that it is more explicit than true / false
1126    #[doc(alias = "gst_event_new_toc")]
1127    #[allow(clippy::new_ret_no_self)]
1128    pub fn new(toc: &crate::Toc, updated: bool) -> Event {
1129        skip_assert_initialized!();
1130        Self::builder(toc, updated).build()
1131    }
1132
1133    pub fn builder(toc: &crate::Toc, updated: bool) -> TocBuilder<'_> {
1134        assert_initialized_main_thread!();
1135        TocBuilder::new(toc, updated)
1136    }
1137}
1138
1139impl Toc {
1140    #[doc(alias = "get_toc")]
1141    #[doc(alias = "gst_event_parse_toc")]
1142    pub fn toc(&self) -> (&crate::TocRef, bool) {
1143        unsafe {
1144            let mut toc = ptr::null_mut();
1145            let mut updated = mem::MaybeUninit::uninit();
1146
1147            ffi::gst_event_parse_toc(self.as_mut_ptr(), &mut toc, updated.as_mut_ptr());
1148            (
1149                crate::TocRef::from_ptr(toc),
1150                from_glib(updated.assume_init()),
1151            )
1152        }
1153    }
1154
1155    #[doc(alias = "get_toc_owned")]
1156    #[doc(alias = "gst_event_parse_toc")]
1157    pub fn toc_owned(&self) -> (crate::Toc, bool) {
1158        unsafe {
1159            let (toc, updated) = self.toc();
1160            (from_glib_none(toc.as_ptr()), updated)
1161        }
1162    }
1163
1164    #[doc(alias = "get_toc")]
1165    #[doc(alias = "gst_event_parse_toc")]
1166    pub fn toc_object(&self) -> &crate::TocRef {
1167        self.toc().0
1168    }
1169
1170    #[doc(alias = "get_toc")]
1171    #[doc(alias = "gst_event_parse_toc")]
1172    pub fn updated(&self) -> bool {
1173        self.toc().1
1174    }
1175}
1176
1177impl_debug_concrete_event!(Toc {
1178    reserved_fields: ["toc", "updated"],
1179    "toc": toc_object,
1180    "updated": updated,
1181});
1182
1183declare_concrete_event!(@sticky Protection, T);
1184impl Protection<Event> {
1185    #[doc(alias = "gst_event_new_protection")]
1186    #[allow(clippy::new_ret_no_self)]
1187    pub fn new(system_id: &str, data: &crate::Buffer) -> Event {
1188        skip_assert_initialized!();
1189        Self::builder(system_id, data).build()
1190    }
1191
1192    pub fn builder<'a>(system_id: &'a str, data: &'a crate::Buffer) -> ProtectionBuilder<'a> {
1193        assert_initialized_main_thread!();
1194        ProtectionBuilder::new(system_id, data)
1195    }
1196}
1197
1198impl Protection {
1199    #[doc(alias = "gst_event_parse_protection")]
1200    pub fn get(&self) -> (&str, &crate::BufferRef, Option<&str>) {
1201        unsafe {
1202            let mut system_id = ptr::null();
1203            let mut buffer = ptr::null_mut();
1204            let mut origin = ptr::null();
1205
1206            ffi::gst_event_parse_protection(
1207                self.as_mut_ptr(),
1208                &mut system_id,
1209                &mut buffer,
1210                &mut origin,
1211            );
1212
1213            (
1214                CStr::from_ptr(system_id).to_str().unwrap(),
1215                crate::BufferRef::from_ptr(buffer),
1216                if origin.is_null() {
1217                    None
1218                } else {
1219                    Some(CStr::from_ptr(origin).to_str().unwrap())
1220                },
1221            )
1222        }
1223    }
1224
1225    #[doc(alias = "gst_event_parse_protection")]
1226    pub fn get_owned(&self) -> (&str, crate::Buffer, Option<&str>) {
1227        unsafe {
1228            let (system_id, buffer, origin) = self.get();
1229            (system_id, from_glib_none(buffer.as_ptr()), origin)
1230        }
1231    }
1232
1233    #[doc(alias = "gst_event_parse_protection")]
1234    pub fn system_id(&self) -> &str {
1235        self.get().0
1236    }
1237
1238    #[doc(alias = "gst_event_parse_protection")]
1239    pub fn buffer(&self) -> &crate::BufferRef {
1240        self.get().1
1241    }
1242
1243    #[doc(alias = "gst_event_parse_protection")]
1244    pub fn origin(&self) -> Option<&str> {
1245        self.get().2
1246    }
1247}
1248
1249impl_debug_concrete_event!(Protection {
1250    reserved_fields: ["data", "system_id", "origin"],
1251    "system-id": system_id,
1252    "buffer": buffer,
1253    "origin": origin,
1254});
1255
1256declare_concrete_event!(SegmentDone, T);
1257impl SegmentDone<Event> {
1258    #[doc(alias = "gst_event_new_segment_done")]
1259    #[allow(clippy::new_ret_no_self)]
1260    pub fn new(position: impl FormattedValue) -> Event {
1261        skip_assert_initialized!();
1262        Self::builder(position).build()
1263    }
1264
1265    pub fn builder<'a>(position: impl FormattedValue) -> SegmentDoneBuilder<'a> {
1266        assert_initialized_main_thread!();
1267        SegmentDoneBuilder::new(position.into())
1268    }
1269}
1270
1271impl SegmentDone {
1272    #[doc(alias = "gst_event_parse_segment_done")]
1273    pub fn get(&self) -> GenericFormattedValue {
1274        unsafe {
1275            let mut fmt = mem::MaybeUninit::uninit();
1276            let mut position = mem::MaybeUninit::uninit();
1277
1278            ffi::gst_event_parse_segment_done(
1279                self.as_mut_ptr(),
1280                fmt.as_mut_ptr(),
1281                position.as_mut_ptr(),
1282            );
1283
1284            GenericFormattedValue::new(from_glib(fmt.assume_init()), position.assume_init())
1285        }
1286    }
1287
1288    #[doc(alias = "gst_event_parse_segment_done")]
1289    pub fn position(&self) -> GenericFormattedValue {
1290        self.get()
1291    }
1292}
1293
1294impl_debug_concrete_event!(SegmentDone {
1295    reserved_fields: ["format", "position"],
1296    "position": position,
1297});
1298
1299declare_concrete_event!(Gap, T);
1300impl Gap<Event> {
1301    #[doc(alias = "gst_event_new_gap")]
1302    #[allow(clippy::new_ret_no_self)]
1303    pub fn new(timestamp: ClockTime, duration: impl Into<Option<ClockTime>>) -> Event {
1304        skip_assert_initialized!();
1305        Self::builder(timestamp).duration(duration).build()
1306    }
1307
1308    pub fn builder<'a>(timestamp: ClockTime) -> GapBuilder<'a> {
1309        assert_initialized_main_thread!();
1310        GapBuilder::new(timestamp)
1311    }
1312}
1313
1314impl Gap {
1315    #[doc(alias = "gst_event_parse_gap")]
1316    pub fn get(&self) -> (ClockTime, Option<ClockTime>) {
1317        unsafe {
1318            let mut timestamp = mem::MaybeUninit::uninit();
1319            let mut duration = mem::MaybeUninit::uninit();
1320
1321            ffi::gst_event_parse_gap(
1322                self.as_mut_ptr(),
1323                timestamp.as_mut_ptr(),
1324                duration.as_mut_ptr(),
1325            );
1326
1327            (
1328                try_from_glib(timestamp.assume_init()).expect("undefined timestamp"),
1329                from_glib(duration.assume_init()),
1330            )
1331        }
1332    }
1333
1334    #[doc(alias = "gst_event_parse_gap")]
1335    pub fn timestamp(&self) -> ClockTime {
1336        self.get().0
1337    }
1338
1339    #[doc(alias = "gst_event_parse_gap")]
1340    pub fn duration(&self) -> Option<ClockTime> {
1341        self.get().1
1342    }
1343
1344    #[cfg(feature = "v1_20")]
1345    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
1346    #[doc(alias = "gst_event_parse_gap_flags")]
1347    pub fn gap_flags(&self) -> crate::GapFlags {
1348        unsafe {
1349            let mut flags = mem::MaybeUninit::uninit();
1350            ffi::gst_event_parse_gap_flags(self.as_mut_ptr(), flags.as_mut_ptr());
1351            from_glib(flags.assume_init())
1352        }
1353    }
1354}
1355
1356impl_debug_concrete_event!(Gap {
1357    reserved_fields: [
1358        "timestamp", "duration",
1359        #[cfg(feature = "v1_20")]
1360        "gap-flags",
1361    ],
1362    "timestamp": timestamp,
1363    "duration": duration,
1364    #[cfg(feature = "v1_20")]
1365    "flags": gap_flags,
1366});
1367
1368#[cfg(feature = "v1_18")]
1369#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1370declare_concrete_event!(@sticky InstantRateChange, T);
1371#[cfg(feature = "v1_18")]
1372#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1373impl InstantRateChange<Event> {
1374    #[doc(alias = "gst_event_new_instant_rate_change")]
1375    #[allow(clippy::new_ret_no_self)]
1376    pub fn new(multiplier: f64, new_flags: crate::SegmentFlags) -> Event {
1377        skip_assert_initialized!();
1378        Self::builder(multiplier, new_flags).build()
1379    }
1380
1381    pub fn builder<'a>(
1382        multiplier: f64,
1383        new_flags: crate::SegmentFlags,
1384    ) -> InstantRateChangeBuilder<'a> {
1385        assert_initialized_main_thread!();
1386        InstantRateChangeBuilder::new(multiplier, new_flags)
1387    }
1388}
1389
1390#[cfg(feature = "v1_18")]
1391#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1392impl InstantRateChange {
1393    #[doc(alias = "gst_event_parse_instant_rate_change")]
1394    pub fn get(&self) -> (f64, crate::SegmentFlags) {
1395        unsafe {
1396            let mut multiplier = mem::MaybeUninit::uninit();
1397            let mut new_flags = mem::MaybeUninit::uninit();
1398
1399            ffi::gst_event_parse_instant_rate_change(
1400                self.as_mut_ptr(),
1401                multiplier.as_mut_ptr(),
1402                new_flags.as_mut_ptr(),
1403            );
1404
1405            (multiplier.assume_init(), from_glib(new_flags.assume_init()))
1406        }
1407    }
1408
1409    #[doc(alias = "gst_event_parse_instant_rate_change")]
1410    pub fn multiplier(&self) -> f64 {
1411        self.get().0
1412    }
1413
1414    #[doc(alias = "gst_event_parse_instant_rate_change")]
1415    pub fn new_flags(&self) -> crate::SegmentFlags {
1416        self.get().1
1417    }
1418}
1419
1420#[cfg(feature = "v1_18")]
1421impl_debug_concrete_event!(InstantRateChange {
1422    reserved_fields: ["rate", "flags"],
1423    "multiplier": multiplier,
1424    "new-flags": new_flags,
1425});
1426
1427declare_concrete_event!(Qos, T);
1428impl Qos<Event> {
1429    #[doc(alias = "gst_event_new_qos")]
1430    #[allow(clippy::new_ret_no_self)]
1431    pub fn new(
1432        type_: crate::QOSType,
1433        proportion: f64,
1434        diff: i64,
1435        timestamp: impl Into<Option<ClockTime>>,
1436    ) -> Event {
1437        skip_assert_initialized!();
1438        Self::builder(type_, proportion, diff)
1439            .timestamp(timestamp)
1440            .build()
1441    }
1442
1443    pub fn builder<'a>(type_: crate::QOSType, proportion: f64, diff: i64) -> QosBuilder<'a> {
1444        assert_initialized_main_thread!();
1445        QosBuilder::new(type_, proportion, diff)
1446    }
1447}
1448
1449impl Qos {
1450    #[doc(alias = "gst_event_parse_qos")]
1451    pub fn get(&self) -> (crate::QOSType, f64, i64, Option<ClockTime>) {
1452        unsafe {
1453            let mut type_ = mem::MaybeUninit::uninit();
1454            let mut proportion = mem::MaybeUninit::uninit();
1455            let mut diff = mem::MaybeUninit::uninit();
1456            let mut timestamp = mem::MaybeUninit::uninit();
1457
1458            ffi::gst_event_parse_qos(
1459                self.as_mut_ptr(),
1460                type_.as_mut_ptr(),
1461                proportion.as_mut_ptr(),
1462                diff.as_mut_ptr(),
1463                timestamp.as_mut_ptr(),
1464            );
1465
1466            (
1467                from_glib(type_.assume_init()),
1468                proportion.assume_init(),
1469                diff.assume_init(),
1470                from_glib(timestamp.assume_init()),
1471            )
1472        }
1473    }
1474
1475    #[doc(alias = "gst_event_parse_qos")]
1476    pub fn qos_type(&self) -> crate::QOSType {
1477        self.get().0
1478    }
1479
1480    #[doc(alias = "gst_event_parse_qos")]
1481    pub fn proportion(&self) -> f64 {
1482        self.get().1
1483    }
1484
1485    #[doc(alias = "gst_event_parse_qos")]
1486    pub fn diff(&self) -> i64 {
1487        self.get().2
1488    }
1489
1490    #[doc(alias = "gst_event_parse_qos")]
1491    pub fn timestamp(&self) -> Option<ClockTime> {
1492        self.get().3
1493    }
1494}
1495
1496impl_debug_concrete_event!(Qos {
1497    reserved_fields: ["type", "proportion", "diff", "timestamp"],
1498    "type": qos_type,
1499    "proportion": proportion,
1500    "diff": diff,
1501    "timestamp": timestamp,
1502});
1503
1504declare_concrete_event!(Seek, T);
1505impl Seek<Event> {
1506    #[doc(alias = "gst_event_new_seek")]
1507    #[allow(clippy::new_ret_no_self)]
1508    pub fn new<V: FormattedValue>(
1509        rate: f64,
1510        flags: crate::SeekFlags,
1511        start_type: crate::SeekType,
1512        start: V,
1513        stop_type: crate::SeekType,
1514        stop: impl CompatibleFormattedValue<V>,
1515    ) -> Event {
1516        skip_assert_initialized!();
1517        Self::builder(rate, flags, start_type, start, stop_type, stop).build()
1518    }
1519
1520    pub fn builder<'a, V: FormattedValue>(
1521        rate: f64,
1522        flags: crate::SeekFlags,
1523        start_type: crate::SeekType,
1524        start: V,
1525        stop_type: crate::SeekType,
1526        stop: impl CompatibleFormattedValue<V>,
1527    ) -> SeekBuilder<'a> {
1528        assert_initialized_main_thread!();
1529        let stop = stop.try_into_checked(start).unwrap();
1530
1531        SeekBuilder::new(
1532            rate,
1533            flags,
1534            start_type,
1535            start.into(),
1536            stop_type,
1537            stop.into(),
1538        )
1539    }
1540}
1541
1542impl Seek {
1543    #[doc(alias = "gst_event_parse_seek")]
1544    pub fn get(
1545        &self,
1546    ) -> (
1547        f64,
1548        crate::SeekFlags,
1549        crate::SeekType,
1550        GenericFormattedValue,
1551        crate::SeekType,
1552        GenericFormattedValue,
1553    ) {
1554        unsafe {
1555            let mut rate = mem::MaybeUninit::uninit();
1556            let mut fmt = mem::MaybeUninit::uninit();
1557            let mut flags = mem::MaybeUninit::uninit();
1558            let mut start_type = mem::MaybeUninit::uninit();
1559            let mut start = mem::MaybeUninit::uninit();
1560            let mut stop_type = mem::MaybeUninit::uninit();
1561            let mut stop = mem::MaybeUninit::uninit();
1562
1563            ffi::gst_event_parse_seek(
1564                self.as_mut_ptr(),
1565                rate.as_mut_ptr(),
1566                fmt.as_mut_ptr(),
1567                flags.as_mut_ptr(),
1568                start_type.as_mut_ptr(),
1569                start.as_mut_ptr(),
1570                stop_type.as_mut_ptr(),
1571                stop.as_mut_ptr(),
1572            );
1573
1574            (
1575                rate.assume_init(),
1576                from_glib(flags.assume_init()),
1577                from_glib(start_type.assume_init()),
1578                GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
1579                from_glib(stop_type.assume_init()),
1580                GenericFormattedValue::new(from_glib(fmt.assume_init()), stop.assume_init()),
1581            )
1582        }
1583    }
1584
1585    #[doc(alias = "gst_event_parse_seek")]
1586    pub fn rate(&self) -> f64 {
1587        self.get().0
1588    }
1589
1590    #[doc(alias = "gst_event_parse_seek")]
1591    pub fn flags(&self) -> crate::SeekFlags {
1592        self.get().1
1593    }
1594
1595    #[doc(alias = "gst_event_parse_seek")]
1596    pub fn start_type(&self) -> crate::SeekType {
1597        self.get().2
1598    }
1599
1600    #[doc(alias = "gst_event_parse_seek")]
1601    pub fn start(&self) -> GenericFormattedValue {
1602        self.get().3
1603    }
1604
1605    #[doc(alias = "gst_event_parse_seek")]
1606    pub fn stop_type(&self) -> crate::SeekType {
1607        self.get().4
1608    }
1609
1610    #[doc(alias = "gst_event_parse_seek")]
1611    pub fn stop(&self) -> GenericFormattedValue {
1612        self.get().5
1613    }
1614
1615    #[cfg(feature = "v1_16")]
1616    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
1617    #[doc(alias = "get_trickmode_interval")]
1618    #[doc(alias = "gst_event_parse_seek_trickmode_interval")]
1619    pub fn trickmode_interval(&self) -> Option<ClockTime> {
1620        unsafe {
1621            let mut trickmode_interval = mem::MaybeUninit::uninit();
1622
1623            ffi::gst_event_parse_seek_trickmode_interval(
1624                self.as_mut_ptr(),
1625                trickmode_interval.as_mut_ptr(),
1626            );
1627
1628            from_glib(trickmode_interval.assume_init())
1629        }
1630    }
1631}
1632
1633impl_debug_concrete_event!(Seek {
1634    reserved_fields: [
1635        "rate", "format", "flags", "cur-type", "cur", "stop-type", "stop",
1636        #[cfg(feature = "v1_16")]
1637        "trickmode-interval",
1638    ],
1639    "rate": rate,
1640    "flags": flags,
1641    "start-type": start_type,
1642    "start": start,
1643    "stop-type": stop_type,
1644    "stop": stop,
1645    #[cfg(feature = "v1_16")]
1646    "trickmode-interval": trickmode_interval,
1647});
1648
1649declare_concrete_event!(Navigation, T);
1650impl Navigation<Event> {
1651    #[doc(alias = "gst_event_new_navigation")]
1652    #[allow(clippy::new_ret_no_self)]
1653    pub fn new(structure: crate::Structure) -> Event {
1654        skip_assert_initialized!();
1655        Self::builder(structure).build()
1656    }
1657
1658    pub fn builder<'a>(structure: crate::Structure) -> NavigationBuilder<'a> {
1659        assert_initialized_main_thread!();
1660        NavigationBuilder::new(structure)
1661    }
1662}
1663
1664impl_debug_concrete_event!(Navigation);
1665
1666declare_concrete_event!(Latency, T);
1667impl Latency<Event> {
1668    #[doc(alias = "gst_event_new_latency")]
1669    #[allow(clippy::new_ret_no_self)]
1670    pub fn new(latency: ClockTime) -> Event {
1671        skip_assert_initialized!();
1672        Self::builder(latency).build()
1673    }
1674
1675    pub fn builder<'a>(latency: ClockTime) -> LatencyBuilder<'a> {
1676        assert_initialized_main_thread!();
1677        LatencyBuilder::new(latency)
1678    }
1679}
1680
1681impl Latency {
1682    #[doc(alias = "get_latency")]
1683    #[doc(alias = "gst_event_parse_latency")]
1684    pub fn latency(&self) -> ClockTime {
1685        unsafe {
1686            let mut latency = mem::MaybeUninit::uninit();
1687
1688            ffi::gst_event_parse_latency(self.as_mut_ptr(), latency.as_mut_ptr());
1689
1690            try_from_glib(latency.assume_init()).expect("undefined latency")
1691        }
1692    }
1693}
1694
1695impl_debug_concrete_event!(Latency {
1696    reserved_fields: ["latency"],
1697    "latency": latency,
1698});
1699
1700declare_concrete_event!(Step, T);
1701impl Step<Event> {
1702    #[doc(alias = "gst_event_new_step")]
1703    #[allow(clippy::new_ret_no_self)]
1704    pub fn new(amount: impl FormattedValue, rate: f64, flush: bool, intermediate: bool) -> Event {
1705        skip_assert_initialized!();
1706        Self::builder(amount, rate, flush, intermediate).build()
1707    }
1708
1709    pub fn builder<'a>(
1710        amount: impl FormattedValue,
1711        rate: f64,
1712        flush: bool,
1713        intermediate: bool,
1714    ) -> StepBuilder<'a> {
1715        assert_initialized_main_thread!();
1716        StepBuilder::new(amount.into(), rate, flush, intermediate)
1717    }
1718}
1719
1720impl Step {
1721    #[doc(alias = "gst_event_parse_step")]
1722    pub fn get(&self) -> (GenericFormattedValue, f64, bool, bool) {
1723        unsafe {
1724            let mut fmt = mem::MaybeUninit::uninit();
1725            let mut amount = mem::MaybeUninit::uninit();
1726            let mut rate = mem::MaybeUninit::uninit();
1727            let mut flush = mem::MaybeUninit::uninit();
1728            let mut intermediate = mem::MaybeUninit::uninit();
1729
1730            ffi::gst_event_parse_step(
1731                self.as_mut_ptr(),
1732                fmt.as_mut_ptr(),
1733                amount.as_mut_ptr(),
1734                rate.as_mut_ptr(),
1735                flush.as_mut_ptr(),
1736                intermediate.as_mut_ptr(),
1737            );
1738
1739            (
1740                GenericFormattedValue::new(
1741                    from_glib(fmt.assume_init()),
1742                    amount.assume_init() as i64,
1743                ),
1744                rate.assume_init(),
1745                from_glib(flush.assume_init()),
1746                from_glib(intermediate.assume_init()),
1747            )
1748        }
1749    }
1750
1751    #[doc(alias = "gst_event_parse_step")]
1752    pub fn amount(&self) -> GenericFormattedValue {
1753        self.get().0
1754    }
1755
1756    #[doc(alias = "gst_event_parse_step")]
1757    pub fn rate(&self) -> f64 {
1758        self.get().1
1759    }
1760
1761    #[doc(alias = "gst_event_parse_step")]
1762    pub fn flush(&self) -> bool {
1763        self.get().2
1764    }
1765
1766    #[doc(alias = "gst_event_parse_step")]
1767    pub fn intermediate(&self) -> bool {
1768        self.get().3
1769    }
1770}
1771
1772impl_debug_concrete_event!(Step {
1773    reserved_fields: ["format", "amount", "rate", "flush", "intermediate"],
1774    "amount": amount,
1775    "rate": rate,
1776    "flush": flush,
1777    "intermediate": intermediate,
1778});
1779
1780declare_concrete_event!(Reconfigure, T);
1781impl Reconfigure<Event> {
1782    #[doc(alias = "gst_event_new_reconfigure")]
1783    #[allow(clippy::new_ret_no_self)]
1784    pub fn new() -> Event {
1785        skip_assert_initialized!();
1786        Self::builder().build()
1787    }
1788
1789    pub fn builder<'a>() -> ReconfigureBuilder<'a> {
1790        assert_initialized_main_thread!();
1791        ReconfigureBuilder::new()
1792    }
1793}
1794
1795impl_debug_concrete_event!(Reconfigure);
1796
1797declare_concrete_event!(TocSelect, T);
1798impl TocSelect<Event> {
1799    #[doc(alias = "gst_event_new_toc_select")]
1800    #[allow(clippy::new_ret_no_self)]
1801    pub fn new(uid: &str) -> Event {
1802        skip_assert_initialized!();
1803        Self::builder(uid).build()
1804    }
1805
1806    pub fn builder(uid: &str) -> TocSelectBuilder<'_> {
1807        assert_initialized_main_thread!();
1808        TocSelectBuilder::new(uid)
1809    }
1810}
1811
1812impl TocSelect {
1813    #[doc(alias = "get_uid")]
1814    pub fn uid(&self) -> &str {
1815        unsafe {
1816            let mut uid = ptr::null_mut();
1817
1818            ffi::gst_event_parse_toc_select(self.as_mut_ptr(), &mut uid);
1819
1820            CStr::from_ptr(uid).to_str().unwrap()
1821        }
1822    }
1823}
1824
1825impl_debug_concrete_event!(TocSelect {
1826    reserved_fields: ["uid"],
1827    "uid": uid,
1828});
1829
1830declare_concrete_event!(SelectStreams, T);
1831impl SelectStreams<Event> {
1832    #[doc(alias = "gst_event_new_select_streams")]
1833    #[allow(clippy::new_ret_no_self)]
1834    pub fn new<'a>(streams: impl IntoIterator<Item = &'a str>) -> Event {
1835        skip_assert_initialized!();
1836        Self::builder(streams).build()
1837    }
1838
1839    pub fn builder<'a>(streams: impl IntoIterator<Item = &'a str>) -> SelectStreamsBuilder<'a> {
1840        assert_initialized_main_thread!();
1841        SelectStreamsBuilder::new(streams)
1842    }
1843}
1844
1845impl SelectStreams {
1846    #[doc(alias = "get_streams")]
1847    #[doc(alias = "gst_event_parse_select_streams")]
1848    pub fn streams(&self) -> glib::collections::List<glib::GStringPtr> {
1849        unsafe {
1850            let mut streams = ptr::null_mut();
1851
1852            ffi::gst_event_parse_select_streams(self.as_mut_ptr(), &mut streams);
1853
1854            glib::collections::List::from_glib_full(streams)
1855        }
1856    }
1857
1858    fn as_streams_debug(&self) -> StreamsDebug<'_> {
1859        StreamsDebug(self)
1860    }
1861}
1862
1863struct StreamsDebug<'a>(&'a SelectStreams);
1864impl std::fmt::Debug for StreamsDebug<'_> {
1865    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1866        f.debug_list().entries(self.0.streams()).finish()
1867    }
1868}
1869
1870impl_debug_concrete_event!(SelectStreams {
1871    reserved_fields: ["streams"],
1872    "streams": as_streams_debug,
1873});
1874
1875#[cfg(feature = "v1_18")]
1876#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1877declare_concrete_event!(InstantRateSyncTime, T);
1878#[cfg(feature = "v1_18")]
1879#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1880impl InstantRateSyncTime<Event> {
1881    #[doc(alias = "gst_event_new_instant_rate_sync_time")]
1882    #[allow(clippy::new_ret_no_self)]
1883    pub fn new(
1884        rate_multiplier: f64,
1885        running_time: ClockTime,
1886        upstream_running_time: ClockTime,
1887    ) -> Event {
1888        skip_assert_initialized!();
1889        Self::builder(rate_multiplier, running_time, upstream_running_time).build()
1890    }
1891
1892    pub fn builder<'a>(
1893        rate_multiplier: f64,
1894        running_time: ClockTime,
1895        upstream_running_time: ClockTime,
1896    ) -> InstantRateSyncTimeBuilder<'a> {
1897        assert_initialized_main_thread!();
1898        InstantRateSyncTimeBuilder::new(rate_multiplier, running_time, upstream_running_time)
1899    }
1900}
1901
1902#[cfg(feature = "v1_18")]
1903#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
1904impl InstantRateSyncTime {
1905    #[doc(alias = "parse_instant_rate_sync_time")]
1906    #[doc(alias = "gst_event_parse_instant_rate_sync_time")]
1907    pub fn get(&self) -> (f64, ClockTime, ClockTime) {
1908        unsafe {
1909            let mut rate_multiplier = mem::MaybeUninit::uninit();
1910            let mut running_time = mem::MaybeUninit::uninit();
1911            let mut upstream_running_time = mem::MaybeUninit::uninit();
1912
1913            ffi::gst_event_parse_instant_rate_sync_time(
1914                self.as_mut_ptr(),
1915                rate_multiplier.as_mut_ptr(),
1916                running_time.as_mut_ptr(),
1917                upstream_running_time.as_mut_ptr(),
1918            );
1919
1920            (
1921                rate_multiplier.assume_init(),
1922                try_from_glib(running_time.assume_init()).expect("undefined timestamp"),
1923                try_from_glib(upstream_running_time.assume_init()).expect("undefined timestamp"),
1924            )
1925        }
1926    }
1927
1928    #[doc(alias = "parse_instant_rate_sync_time")]
1929    #[doc(alias = "gst_event_parse_instant_rate_sync_time")]
1930    pub fn rate_multiplier(&self) -> f64 {
1931        self.get().0
1932    }
1933
1934    #[doc(alias = "parse_instant_rate_sync_time")]
1935    #[doc(alias = "gst_event_parse_instant_rate_sync_time")]
1936    pub fn running_time(&self) -> ClockTime {
1937        self.get().1
1938    }
1939
1940    #[doc(alias = "parse_instant_rate_sync_time")]
1941    #[doc(alias = "gst_event_parse_instant_rate_sync_time")]
1942    pub fn upstream_running_time(&self) -> ClockTime {
1943        self.get().2
1944    }
1945}
1946
1947#[cfg(feature = "v1_18")]
1948impl_debug_concrete_event!(InstantRateSyncTime {
1949    reserved_fields: ["rate", "running-time", "upstream-running-time"],
1950    "rate-multiplier": rate_multiplier,
1951    "running_time": running_time,
1952    "upstream_running_time": upstream_running_time,
1953});
1954
1955declare_concrete_event!(CustomUpstream, T);
1956impl CustomUpstream<Event> {
1957    #[doc(alias = "gst_event_new_custom")]
1958    #[allow(clippy::new_ret_no_self)]
1959    pub fn new(structure: crate::Structure) -> Event {
1960        skip_assert_initialized!();
1961        Self::builder(structure).build()
1962    }
1963
1964    pub fn builder<'a>(structure: crate::Structure) -> CustomUpstreamBuilder<'a> {
1965        assert_initialized_main_thread!();
1966        CustomUpstreamBuilder::new(structure)
1967    }
1968}
1969
1970impl_debug_concrete_event!(CustomUpstream);
1971
1972declare_concrete_event!(CustomDownstream, T);
1973impl CustomDownstream<Event> {
1974    #[doc(alias = "gst_event_new_custom")]
1975    #[allow(clippy::new_ret_no_self)]
1976    pub fn new(structure: crate::Structure) -> Event {
1977        skip_assert_initialized!();
1978        Self::builder(structure).build()
1979    }
1980
1981    pub fn builder<'a>(structure: crate::Structure) -> CustomDownstreamBuilder<'a> {
1982        assert_initialized_main_thread!();
1983        CustomDownstreamBuilder::new(structure)
1984    }
1985}
1986
1987impl_debug_concrete_event!(CustomDownstream);
1988
1989declare_concrete_event!(CustomDownstreamOob, T);
1990impl CustomDownstreamOob<Event> {
1991    #[doc(alias = "gst_event_new_custom")]
1992    #[allow(clippy::new_ret_no_self)]
1993    pub fn new(structure: crate::Structure) -> Event {
1994        skip_assert_initialized!();
1995        Self::builder(structure).build()
1996    }
1997
1998    pub fn builder<'a>(structure: crate::Structure) -> CustomDownstreamOobBuilder<'a> {
1999        assert_initialized_main_thread!();
2000        CustomDownstreamOobBuilder::new(structure)
2001    }
2002}
2003
2004impl_debug_concrete_event!(CustomDownstreamOob);
2005
2006declare_concrete_event!(@sticky CustomDownstreamSticky, T);
2007impl CustomDownstreamSticky<Event> {
2008    #[doc(alias = "gst_event_new_custom")]
2009    #[allow(clippy::new_ret_no_self)]
2010    pub fn new(structure: crate::Structure) -> Event {
2011        skip_assert_initialized!();
2012        Self::builder(structure).build()
2013    }
2014
2015    pub fn builder<'a>(structure: crate::Structure) -> CustomDownstreamStickyBuilder<'a> {
2016        assert_initialized_main_thread!();
2017        CustomDownstreamStickyBuilder::new(structure)
2018    }
2019}
2020
2021impl_debug_concrete_event!(CustomDownstreamSticky);
2022
2023declare_concrete_event!(CustomBoth, T);
2024impl CustomBoth<Event> {
2025    #[doc(alias = "gst_event_new_custom")]
2026    #[allow(clippy::new_ret_no_self)]
2027    pub fn new(structure: crate::Structure) -> Event {
2028        skip_assert_initialized!();
2029        Self::builder(structure).build()
2030    }
2031
2032    pub fn builder<'a>(structure: crate::Structure) -> CustomBothBuilder<'a> {
2033        assert_initialized_main_thread!();
2034        CustomBothBuilder::new(structure)
2035    }
2036}
2037
2038impl_debug_concrete_event!(CustomBoth);
2039
2040declare_concrete_event!(CustomBothOob, T);
2041impl CustomBothOob<Event> {
2042    #[doc(alias = "gst_event_new_custom")]
2043    #[allow(clippy::new_ret_no_self)]
2044    pub fn new(structure: crate::Structure) -> Event {
2045        skip_assert_initialized!();
2046        Self::builder(structure).build()
2047    }
2048
2049    pub fn builder<'a>(structure: crate::Structure) -> CustomBothOobBuilder<'a> {
2050        assert_initialized_main_thread!();
2051        CustomBothOobBuilder::new(structure)
2052    }
2053}
2054
2055impl_debug_concrete_event!(CustomBothOob);
2056
2057declare_concrete_event!(Other, T);
2058impl_debug_concrete_event!(Other);
2059
2060struct EventBuilder<'a> {
2061    seqnum: Option<Seqnum>,
2062    running_time_offset: Option<i64>,
2063    other_fields: Vec<(&'a str, glib::SendValue)>,
2064}
2065
2066impl<'a> EventBuilder<'a> {
2067    fn new() -> Self {
2068        Self {
2069            seqnum: None,
2070            running_time_offset: None,
2071            other_fields: Vec::new(),
2072        }
2073    }
2074
2075    fn seqnum(self, seqnum: Seqnum) -> Self {
2076        Self {
2077            seqnum: Some(seqnum),
2078            ..self
2079        }
2080    }
2081
2082    fn running_time_offset(self, running_time_offset: i64) -> Self {
2083        Self {
2084            running_time_offset: Some(running_time_offset),
2085            ..self
2086        }
2087    }
2088
2089    fn other_field(self, name: &'a str, value: impl ToSendValue) -> Self {
2090        let mut other_fields = self.other_fields;
2091        other_fields.push((name, value.to_send_value()));
2092
2093        Self {
2094            other_fields,
2095            ..self
2096        }
2097    }
2098}
2099
2100macro_rules! event_builder_generic_impl {
2101    ($new_fn:expr) => {
2102        #[doc(alias = "gst_event_set_seqnum")]
2103        #[allow(clippy::needless_update)]
2104        pub fn seqnum(self, seqnum: Seqnum) -> Self {
2105            Self {
2106                builder: self.builder.seqnum(seqnum),
2107                ..self
2108            }
2109        }
2110
2111        #[doc(alias = "gst_event_set_seqnum")]
2112        #[allow(clippy::needless_update)]
2113        pub fn seqnum_if(self, seqnum: Seqnum, predicate: bool) -> Self {
2114            if predicate { self.seqnum(seqnum) } else { self }
2115        }
2116
2117        #[doc(alias = "gst_event_set_seqnum")]
2118        #[allow(clippy::needless_update)]
2119        pub fn seqnum_if_some(self, seqnum: Option<Seqnum>) -> Self {
2120            if let Some(seqnum) = seqnum {
2121                self.seqnum(seqnum)
2122            } else {
2123                self
2124            }
2125        }
2126
2127        #[doc(alias = "gst_event_set_running_time_offset")]
2128        #[allow(clippy::needless_update)]
2129        pub fn running_time_offset(self, running_time_offset: i64) -> Self {
2130            Self {
2131                builder: self.builder.running_time_offset(running_time_offset),
2132                ..self
2133            }
2134        }
2135
2136        #[doc(alias = "gst_event_set_running_time_offset")]
2137        #[allow(clippy::needless_update)]
2138        pub fn running_time_offset_if(self, running_time_offset: i64, predicate: bool) -> Self {
2139            if predicate {
2140                self.running_time_offset(running_time_offset)
2141            } else {
2142                self
2143            }
2144        }
2145
2146        #[doc(alias = "gst_event_set_running_time_offset")]
2147        #[allow(clippy::needless_update)]
2148        pub fn running_time_offset_if_some(self, running_time_offset: Option<i64>) -> Self {
2149            if let Some(running_time_offset) = running_time_offset {
2150                self.running_time_offset(running_time_offset)
2151            } else {
2152                self
2153            }
2154        }
2155
2156        // rustdoc-stripper-ignore-next
2157        /// Sets field `name` to the given value `value`.
2158        ///
2159        /// Overrides any default or previously defined value for `name`.
2160        #[allow(clippy::needless_update)]
2161        pub fn other_field(self, name: &'a str, value: impl ToSendValue) -> Self {
2162            Self {
2163                builder: self.builder.other_field(name, value),
2164                ..self
2165            }
2166        }
2167
2168        impl_builder_gvalue_extra_setters!(other_field);
2169
2170        #[must_use = "Building the event without using it has no effect"]
2171        #[allow(clippy::redundant_closure_call)]
2172        pub fn build(mut self) -> Event {
2173            unsafe {
2174                let event = $new_fn(&mut self);
2175                if let Some(seqnum) = self.builder.seqnum {
2176                    ffi::gst_event_set_seqnum(event, seqnum.0.get());
2177                }
2178
2179                if let Some(running_time_offset) = self.builder.running_time_offset {
2180                    ffi::gst_event_set_running_time_offset(event, running_time_offset);
2181                }
2182
2183                if !self.builder.other_fields.is_empty() {
2184                    let s = StructureRef::from_glib_borrow_mut(ffi::gst_event_writable_structure(
2185                        event,
2186                    ));
2187
2188                    for (k, v) in self.builder.other_fields {
2189                        s.set_value(k, v);
2190                    }
2191                }
2192
2193                from_glib_full(event)
2194            }
2195        }
2196    };
2197}
2198
2199#[must_use = "The builder must be built to be used"]
2200pub struct FlushStartBuilder<'a> {
2201    builder: EventBuilder<'a>,
2202}
2203
2204impl<'a> FlushStartBuilder<'a> {
2205    fn new() -> Self {
2206        skip_assert_initialized!();
2207        Self {
2208            builder: EventBuilder::new(),
2209        }
2210    }
2211
2212    event_builder_generic_impl!(|_| { ffi::gst_event_new_flush_start() });
2213}
2214
2215#[must_use = "The builder must be built to be used"]
2216pub struct FlushStopBuilder<'a> {
2217    builder: EventBuilder<'a>,
2218    reset_time: bool,
2219}
2220impl<'a> FlushStopBuilder<'a> {
2221    fn new(reset_time: bool) -> Self {
2222        skip_assert_initialized!();
2223        Self {
2224            builder: EventBuilder::new(),
2225            reset_time,
2226        }
2227    }
2228
2229    event_builder_generic_impl!(|s: &Self| {
2230        ffi::gst_event_new_flush_stop(s.reset_time.into_glib())
2231    });
2232}
2233
2234#[must_use = "The builder must be built to be used"]
2235pub struct StreamStartBuilder<'a> {
2236    builder: EventBuilder<'a>,
2237    stream_id: &'a str,
2238    flags: Option<crate::StreamFlags>,
2239    group_id: Option<GroupId>,
2240    stream: Option<crate::Stream>,
2241}
2242
2243impl<'a> StreamStartBuilder<'a> {
2244    fn new(stream_id: &'a str) -> Self {
2245        skip_assert_initialized!();
2246        Self {
2247            builder: EventBuilder::new(),
2248            stream_id,
2249            flags: None,
2250            group_id: None,
2251            stream: None,
2252        }
2253    }
2254
2255    pub fn flags(self, flags: crate::StreamFlags) -> Self {
2256        Self {
2257            flags: Some(flags),
2258            ..self
2259        }
2260    }
2261
2262    pub fn flags_if(self, flags: crate::StreamFlags, predicate: bool) -> Self {
2263        if predicate { self.flags(flags) } else { self }
2264    }
2265
2266    pub fn flags_if_some(self, flags: Option<crate::StreamFlags>) -> Self {
2267        if let Some(flags) = flags {
2268            self.flags(flags)
2269        } else {
2270            self
2271        }
2272    }
2273
2274    pub fn group_id(self, group_id: GroupId) -> Self {
2275        Self {
2276            group_id: Some(group_id),
2277            ..self
2278        }
2279    }
2280
2281    pub fn group_id_if(self, group_id: GroupId, predicate: bool) -> Self {
2282        if predicate {
2283            self.group_id(group_id)
2284        } else {
2285            self
2286        }
2287    }
2288
2289    pub fn group_id_if_some(self, group_id: Option<GroupId>) -> Self {
2290        if let Some(group_id) = group_id {
2291            self.group_id(group_id)
2292        } else {
2293            self
2294        }
2295    }
2296
2297    pub fn stream(self, stream: crate::Stream) -> Self {
2298        Self {
2299            stream: Some(stream),
2300            ..self
2301        }
2302    }
2303
2304    pub fn stream_if(self, stream: crate::Stream, predicate: bool) -> Self {
2305        if predicate { self.stream(stream) } else { self }
2306    }
2307
2308    pub fn stream_if_some(self, stream: Option<crate::Stream>) -> Self {
2309        if let Some(stream) = stream {
2310            self.stream(stream)
2311        } else {
2312            self
2313        }
2314    }
2315
2316    event_builder_generic_impl!(|s: &Self| {
2317        let ev = ffi::gst_event_new_stream_start(s.stream_id.to_glib_none().0);
2318        if let Some(flags) = s.flags {
2319            ffi::gst_event_set_stream_flags(ev, flags.into_glib());
2320        }
2321        if let Some(group_id) = s.group_id {
2322            ffi::gst_event_set_group_id(ev, group_id.0.get());
2323        }
2324
2325        if let Some(ref stream) = s.stream {
2326            ffi::gst_event_set_stream(ev, stream.to_glib_none().0);
2327        }
2328
2329        ev
2330    });
2331}
2332
2333#[must_use = "The builder must be built to be used"]
2334pub struct CapsBuilder<'a> {
2335    builder: EventBuilder<'a>,
2336    caps: &'a crate::Caps,
2337}
2338
2339impl<'a> CapsBuilder<'a> {
2340    fn new(caps: &'a crate::Caps) -> Self {
2341        skip_assert_initialized!();
2342        Self {
2343            builder: EventBuilder::new(),
2344            caps,
2345        }
2346    }
2347
2348    event_builder_generic_impl!(|s: &Self| { ffi::gst_event_new_caps(s.caps.as_mut_ptr()) });
2349}
2350
2351#[must_use = "The builder must be built to be used"]
2352pub struct SegmentBuilder<'a> {
2353    builder: EventBuilder<'a>,
2354    segment: &'a crate::Segment,
2355}
2356
2357impl<'a> SegmentBuilder<'a> {
2358    fn new(segment: &'a crate::Segment) -> Self {
2359        skip_assert_initialized!();
2360        Self {
2361            builder: EventBuilder::new(),
2362            segment,
2363        }
2364    }
2365
2366    event_builder_generic_impl!(|s: &Self| {
2367        ffi::gst_event_new_segment(s.segment.to_glib_none().0)
2368    });
2369}
2370
2371#[must_use = "The builder must be built to be used"]
2372pub struct StreamCollectionBuilder<'a> {
2373    builder: EventBuilder<'a>,
2374    stream_collection: &'a crate::StreamCollection,
2375}
2376
2377impl<'a> StreamCollectionBuilder<'a> {
2378    fn new(stream_collection: &'a crate::StreamCollection) -> Self {
2379        skip_assert_initialized!();
2380        Self {
2381            builder: EventBuilder::new(),
2382            stream_collection,
2383        }
2384    }
2385
2386    event_builder_generic_impl!(|s: &Self| {
2387        ffi::gst_event_new_stream_collection(s.stream_collection.to_glib_none().0)
2388    });
2389}
2390
2391#[cfg(feature = "v1_18")]
2392#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
2393#[must_use = "The builder must be built to be used"]
2394pub struct InstantRateSyncTimeBuilder<'a> {
2395    builder: EventBuilder<'a>,
2396    rate_multiplier: f64,
2397    running_time: ClockTime,
2398    upstream_running_time: ClockTime,
2399}
2400
2401#[cfg(feature = "v1_18")]
2402#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
2403impl<'a> InstantRateSyncTimeBuilder<'a> {
2404    fn new(
2405        rate_multiplier: f64,
2406        running_time: ClockTime,
2407        upstream_running_time: ClockTime,
2408    ) -> Self {
2409        skip_assert_initialized!();
2410        Self {
2411            builder: EventBuilder::new(),
2412            rate_multiplier,
2413            running_time,
2414            upstream_running_time,
2415        }
2416    }
2417
2418    event_builder_generic_impl!(|s: &Self| {
2419        ffi::gst_event_new_instant_rate_sync_time(
2420            s.rate_multiplier,
2421            s.running_time.into_glib(),
2422            s.upstream_running_time.into_glib(),
2423        )
2424    });
2425}
2426
2427#[must_use = "The builder must be built to be used"]
2428pub struct TagBuilder<'a> {
2429    builder: EventBuilder<'a>,
2430    tags: Option<crate::TagList>,
2431}
2432
2433impl<'a> TagBuilder<'a> {
2434    fn new(tags: crate::TagList) -> Self {
2435        skip_assert_initialized!();
2436        Self {
2437            builder: EventBuilder::new(),
2438            tags: Some(tags),
2439        }
2440    }
2441
2442    event_builder_generic_impl!(|s: &mut Self| {
2443        let tags = s.tags.take().unwrap();
2444        ffi::gst_event_new_tag(tags.into_glib_ptr())
2445    });
2446}
2447
2448#[must_use = "The builder must be built to be used"]
2449pub struct BuffersizeBuilder<'a> {
2450    builder: EventBuilder<'a>,
2451    minsize: GenericFormattedValue,
2452    maxsize: GenericFormattedValue,
2453    r#async: bool,
2454}
2455
2456impl<'a> BuffersizeBuilder<'a> {
2457    fn new(minsize: GenericFormattedValue, maxsize: GenericFormattedValue, r#async: bool) -> Self {
2458        skip_assert_initialized!();
2459        Self {
2460            builder: EventBuilder::new(),
2461            minsize,
2462            maxsize,
2463            r#async,
2464        }
2465    }
2466
2467    event_builder_generic_impl!(|s: &Self| {
2468        ffi::gst_event_new_buffer_size(
2469            s.minsize.format().into_glib(),
2470            s.minsize.value(),
2471            s.maxsize.value(),
2472            s.r#async.into_glib(),
2473        )
2474    });
2475}
2476
2477#[must_use = "The builder must be built to be used"]
2478pub struct SinkMessageBuilder<'a> {
2479    builder: EventBuilder<'a>,
2480    name: &'a str,
2481    msg: &'a crate::Message,
2482}
2483
2484impl<'a> SinkMessageBuilder<'a> {
2485    fn new(name: &'a str, msg: &'a crate::Message) -> Self {
2486        skip_assert_initialized!();
2487        Self {
2488            builder: EventBuilder::new(),
2489            name,
2490            msg,
2491        }
2492    }
2493
2494    event_builder_generic_impl!(|s: &Self| {
2495        ffi::gst_event_new_sink_message(s.name.to_glib_none().0, s.msg.as_mut_ptr())
2496    });
2497}
2498
2499#[must_use = "The builder must be built to be used"]
2500pub struct StreamGroupDoneBuilder<'a> {
2501    builder: EventBuilder<'a>,
2502    group_id: GroupId,
2503}
2504
2505impl<'a> StreamGroupDoneBuilder<'a> {
2506    fn new(group_id: GroupId) -> Self {
2507        skip_assert_initialized!();
2508        Self {
2509            builder: EventBuilder::new(),
2510            group_id,
2511        }
2512    }
2513
2514    event_builder_generic_impl!(|s: &Self| {
2515        ffi::gst_event_new_stream_group_done(s.group_id.0.get())
2516    });
2517}
2518
2519#[must_use = "The builder must be built to be used"]
2520pub struct EosBuilder<'a> {
2521    builder: EventBuilder<'a>,
2522}
2523
2524impl<'a> EosBuilder<'a> {
2525    fn new() -> Self {
2526        skip_assert_initialized!();
2527        Self {
2528            builder: EventBuilder::new(),
2529        }
2530    }
2531
2532    event_builder_generic_impl!(|_| ffi::gst_event_new_eos());
2533}
2534
2535#[must_use = "The builder must be built to be used"]
2536pub struct TocBuilder<'a> {
2537    builder: EventBuilder<'a>,
2538    toc: &'a crate::Toc,
2539    updated: bool,
2540}
2541
2542impl<'a> TocBuilder<'a> {
2543    fn new(toc: &'a crate::Toc, updated: bool) -> Self {
2544        skip_assert_initialized!();
2545        Self {
2546            builder: EventBuilder::new(),
2547            toc,
2548            updated,
2549        }
2550    }
2551
2552    event_builder_generic_impl!(|s: &Self| ffi::gst_event_new_toc(
2553        s.toc.to_glib_none().0,
2554        s.updated.into_glib()
2555    ));
2556}
2557
2558#[must_use = "The builder must be built to be used"]
2559pub struct ProtectionBuilder<'a> {
2560    builder: EventBuilder<'a>,
2561    system_id: &'a str,
2562    data: &'a crate::Buffer,
2563    origin: Option<&'a str>,
2564}
2565
2566impl<'a> ProtectionBuilder<'a> {
2567    fn new(system_id: &'a str, data: &'a crate::Buffer) -> Self {
2568        skip_assert_initialized!();
2569        Self {
2570            builder: EventBuilder::new(),
2571            system_id,
2572            data,
2573            origin: None,
2574        }
2575    }
2576
2577    pub fn origin(self, origin: &'a str) -> Self {
2578        Self {
2579            origin: Some(origin),
2580            ..self
2581        }
2582    }
2583
2584    pub fn origin_if(self, origin: &'a str, predicate: bool) -> Self {
2585        if predicate { self.origin(origin) } else { self }
2586    }
2587
2588    pub fn origin_if_some(self, origin: Option<&'a str>) -> Self {
2589        if let Some(origin) = origin {
2590            self.origin(origin)
2591        } else {
2592            self
2593        }
2594    }
2595
2596    event_builder_generic_impl!(|s: &Self| {
2597        ffi::gst_event_new_protection(
2598            s.system_id.to_glib_none().0,
2599            s.data.as_mut_ptr(),
2600            s.origin.to_glib_none().0,
2601        )
2602    });
2603}
2604
2605#[must_use = "The builder must be built to be used"]
2606pub struct SegmentDoneBuilder<'a> {
2607    builder: EventBuilder<'a>,
2608    position: GenericFormattedValue,
2609}
2610
2611impl<'a> SegmentDoneBuilder<'a> {
2612    fn new(position: GenericFormattedValue) -> Self {
2613        skip_assert_initialized!();
2614        Self {
2615            builder: EventBuilder::new(),
2616            position,
2617        }
2618    }
2619
2620    event_builder_generic_impl!(|s: &Self| {
2621        ffi::gst_event_new_segment_done(s.position.format().into_glib(), s.position.value())
2622    });
2623}
2624
2625#[must_use = "The builder must be built to be used"]
2626pub struct GapBuilder<'a> {
2627    builder: EventBuilder<'a>,
2628    timestamp: ClockTime,
2629    duration: Option<ClockTime>,
2630    #[cfg(feature = "v1_20")]
2631    gap_flags: Option<crate::GapFlags>,
2632}
2633
2634impl<'a> GapBuilder<'a> {
2635    fn new(timestamp: ClockTime) -> Self {
2636        skip_assert_initialized!();
2637        Self {
2638            builder: EventBuilder::new(),
2639            timestamp,
2640            duration: None,
2641            #[cfg(feature = "v1_20")]
2642            gap_flags: None,
2643        }
2644    }
2645
2646    #[cfg(feature = "v1_20")]
2647    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
2648    pub fn gap_flags(mut self, flags: crate::GapFlags) -> Self {
2649        self.gap_flags = Some(flags);
2650        self
2651    }
2652
2653    #[cfg(feature = "v1_20")]
2654    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
2655    pub fn gap_flags_if(self, flags: crate::GapFlags, predicate: bool) -> Self {
2656        if predicate {
2657            self.gap_flags(flags)
2658        } else {
2659            self
2660        }
2661    }
2662
2663    #[cfg(feature = "v1_20")]
2664    #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
2665    pub fn gap_flags_if_some(self, flags: Option<crate::GapFlags>) -> Self {
2666        if let Some(flags) = flags {
2667            self.gap_flags(flags)
2668        } else {
2669            self
2670        }
2671    }
2672
2673    pub fn duration(mut self, duration: impl Into<Option<ClockTime>>) -> Self {
2674        self.duration = duration.into();
2675        self
2676    }
2677
2678    pub fn duration_if(self, duration: ClockTime, predicate: bool) -> Self {
2679        if predicate {
2680            self.duration(duration)
2681        } else {
2682            self
2683        }
2684    }
2685
2686    pub fn duration_if_some(self, duration: Option<ClockTime>) -> Self {
2687        if let Some(duration) = duration {
2688            self.duration(duration)
2689        } else {
2690            self
2691        }
2692    }
2693
2694    event_builder_generic_impl!(|s: &Self| {
2695        #[allow(clippy::let_and_return)]
2696        let ev = ffi::gst_event_new_gap(s.timestamp.into_glib(), s.duration.into_glib());
2697
2698        #[cfg(feature = "v1_20")]
2699        if let Some(ref flags) = s.gap_flags {
2700            ffi::gst_event_set_gap_flags(ev, flags.into_glib());
2701        }
2702
2703        ev
2704    });
2705}
2706
2707#[cfg(feature = "v1_18")]
2708#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
2709#[must_use = "The builder must be built to be used"]
2710pub struct InstantRateChangeBuilder<'a> {
2711    builder: EventBuilder<'a>,
2712    multiplier: f64,
2713    new_flags: crate::SegmentFlags,
2714}
2715
2716#[cfg(feature = "v1_18")]
2717#[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
2718impl<'a> InstantRateChangeBuilder<'a> {
2719    fn new(multiplier: f64, new_flags: crate::SegmentFlags) -> Self {
2720        skip_assert_initialized!();
2721        Self {
2722            builder: EventBuilder::new(),
2723            multiplier,
2724            new_flags,
2725        }
2726    }
2727
2728    event_builder_generic_impl!(|s: &Self| ffi::gst_event_new_instant_rate_change(
2729        s.multiplier,
2730        s.new_flags.into_glib()
2731    ));
2732}
2733
2734#[must_use = "The builder must be built to be used"]
2735pub struct QosBuilder<'a> {
2736    builder: EventBuilder<'a>,
2737    type_: crate::QOSType,
2738    proportion: f64,
2739    diff: i64,
2740    timestamp: Option<ClockTime>,
2741}
2742
2743impl<'a> QosBuilder<'a> {
2744    fn new(type_: crate::QOSType, proportion: f64, diff: i64) -> Self {
2745        skip_assert_initialized!();
2746        Self {
2747            builder: EventBuilder::new(),
2748            type_,
2749            proportion,
2750            diff,
2751            timestamp: None,
2752        }
2753    }
2754
2755    pub fn timestamp(mut self, timestamp: impl Into<Option<ClockTime>>) -> Self {
2756        self.timestamp = timestamp.into();
2757        self
2758    }
2759
2760    pub fn timestamp_if(self, timestamp: ClockTime, predicate: bool) -> Self {
2761        if predicate {
2762            self.timestamp(timestamp)
2763        } else {
2764            self
2765        }
2766    }
2767
2768    pub fn timestamp_if_some(self, timestamp: Option<ClockTime>) -> Self {
2769        if let Some(timestamp) = timestamp {
2770            self.timestamp(timestamp)
2771        } else {
2772            self
2773        }
2774    }
2775
2776    event_builder_generic_impl!(|s: &Self| ffi::gst_event_new_qos(
2777        s.type_.into_glib(),
2778        s.proportion,
2779        s.diff,
2780        s.timestamp.into_glib(),
2781    ));
2782}
2783
2784#[must_use = "The builder must be built to be used"]
2785pub struct SeekBuilder<'a> {
2786    builder: EventBuilder<'a>,
2787    rate: f64,
2788    flags: crate::SeekFlags,
2789    start_type: crate::SeekType,
2790    start: GenericFormattedValue,
2791    stop_type: crate::SeekType,
2792    stop: GenericFormattedValue,
2793    #[allow(unused)]
2794    trickmode_interval: Option<ClockTime>,
2795}
2796
2797impl<'a> SeekBuilder<'a> {
2798    fn new(
2799        rate: f64,
2800        flags: crate::SeekFlags,
2801        start_type: crate::SeekType,
2802        start: GenericFormattedValue,
2803        stop_type: crate::SeekType,
2804        stop: GenericFormattedValue,
2805    ) -> Self {
2806        skip_assert_initialized!();
2807        Self {
2808            builder: EventBuilder::new(),
2809            rate,
2810            flags,
2811            start_type,
2812            start,
2813            stop_type,
2814            stop,
2815            trickmode_interval: None,
2816        }
2817    }
2818
2819    pub fn trickmode_interval(mut self, trickmode_interval: impl Into<Option<ClockTime>>) -> Self {
2820        self.trickmode_interval = trickmode_interval.into();
2821        self
2822    }
2823
2824    event_builder_generic_impl!(|s: &Self| {
2825        #[allow(clippy::let_and_return)]
2826        {
2827            let ev = ffi::gst_event_new_seek(
2828                s.rate,
2829                s.start.format().into_glib(),
2830                s.flags.into_glib(),
2831                s.start_type.into_glib(),
2832                s.start.value(),
2833                s.stop_type.into_glib(),
2834                s.stop.value(),
2835            );
2836
2837            #[cfg(feature = "v1_16")]
2838            if let Some(trickmode_interval) = s.trickmode_interval {
2839                ffi::gst_event_set_seek_trickmode_interval(ev, trickmode_interval.into_glib());
2840            }
2841
2842            ev
2843        }
2844    });
2845}
2846
2847#[must_use = "The builder must be built to be used"]
2848pub struct NavigationBuilder<'a> {
2849    builder: EventBuilder<'a>,
2850    structure: Option<Structure>,
2851}
2852
2853impl<'a> NavigationBuilder<'a> {
2854    fn new(structure: Structure) -> Self {
2855        skip_assert_initialized!();
2856        Self {
2857            builder: EventBuilder::new(),
2858            structure: Some(structure),
2859        }
2860    }
2861
2862    event_builder_generic_impl!(|s: &mut Self| {
2863        let structure = s.structure.take().unwrap();
2864        ffi::gst_event_new_navigation(structure.into_glib_ptr())
2865    });
2866}
2867
2868#[must_use = "The builder must be built to be used"]
2869pub struct LatencyBuilder<'a> {
2870    builder: EventBuilder<'a>,
2871    latency: ClockTime,
2872}
2873
2874impl<'a> LatencyBuilder<'a> {
2875    fn new(latency: ClockTime) -> Self {
2876        skip_assert_initialized!();
2877        Self {
2878            builder: EventBuilder::new(),
2879            latency,
2880        }
2881    }
2882
2883    event_builder_generic_impl!(|s: &Self| { ffi::gst_event_new_latency(s.latency.into_glib()) });
2884}
2885
2886#[must_use = "The builder must be built to be used"]
2887pub struct StepBuilder<'a> {
2888    builder: EventBuilder<'a>,
2889    amount: GenericFormattedValue,
2890    rate: f64,
2891    flush: bool,
2892    intermediate: bool,
2893}
2894
2895impl<'a> StepBuilder<'a> {
2896    fn new(amount: GenericFormattedValue, rate: f64, flush: bool, intermediate: bool) -> Self {
2897        skip_assert_initialized!();
2898        Self {
2899            builder: EventBuilder::new(),
2900            amount,
2901            rate,
2902            flush,
2903            intermediate,
2904        }
2905    }
2906
2907    event_builder_generic_impl!(|s: &Self| {
2908        ffi::gst_event_new_step(
2909            s.amount.format().into_glib(),
2910            s.amount.value() as u64,
2911            s.rate,
2912            s.flush.into_glib(),
2913            s.intermediate.into_glib(),
2914        )
2915    });
2916}
2917
2918#[must_use = "The builder must be built to be used"]
2919pub struct ReconfigureBuilder<'a> {
2920    builder: EventBuilder<'a>,
2921}
2922
2923impl<'a> ReconfigureBuilder<'a> {
2924    fn new() -> Self {
2925        skip_assert_initialized!();
2926        Self {
2927            builder: EventBuilder::new(),
2928        }
2929    }
2930
2931    event_builder_generic_impl!(|_| { ffi::gst_event_new_reconfigure() });
2932}
2933
2934#[must_use = "The builder must be built to be used"]
2935pub struct TocSelectBuilder<'a> {
2936    builder: EventBuilder<'a>,
2937    uid: &'a str,
2938}
2939
2940impl<'a> TocSelectBuilder<'a> {
2941    fn new(uid: &'a str) -> Self {
2942        skip_assert_initialized!();
2943        Self {
2944            builder: EventBuilder::new(),
2945            uid,
2946        }
2947    }
2948
2949    event_builder_generic_impl!(|s: &Self| {
2950        ffi::gst_event_new_toc_select(s.uid.to_glib_none().0)
2951    });
2952}
2953
2954#[must_use = "The builder must be built to be used"]
2955pub struct SelectStreamsBuilder<'a> {
2956    builder: EventBuilder<'a>,
2957    streams: glib::collections::List<glib::GStringPtr>,
2958}
2959
2960impl<'a> SelectStreamsBuilder<'a> {
2961    fn new(streams: impl IntoIterator<Item = &'a str>) -> Self {
2962        skip_assert_initialized!();
2963        Self {
2964            builder: EventBuilder::new(),
2965            streams: streams.into_iter().map(glib::GStringPtr::from).collect(),
2966        }
2967    }
2968
2969    event_builder_generic_impl!(|s: &Self| {
2970        ffi::gst_event_new_select_streams(mut_override(s.streams.as_ptr()))
2971    });
2972}
2973
2974#[must_use = "The builder must be built to be used"]
2975pub struct CustomUpstreamBuilder<'a> {
2976    builder: EventBuilder<'a>,
2977    structure: Option<Structure>,
2978}
2979
2980impl<'a> CustomUpstreamBuilder<'a> {
2981    fn new(structure: Structure) -> Self {
2982        skip_assert_initialized!();
2983        Self {
2984            builder: EventBuilder::new(),
2985            structure: Some(structure),
2986        }
2987    }
2988
2989    event_builder_generic_impl!(|s: &mut Self| {
2990        let structure = s.structure.take().unwrap();
2991        ffi::gst_event_new_custom(ffi::GST_EVENT_CUSTOM_UPSTREAM, structure.into_glib_ptr())
2992    });
2993}
2994
2995#[must_use = "The builder must be built to be used"]
2996pub struct CustomDownstreamBuilder<'a> {
2997    builder: EventBuilder<'a>,
2998    structure: Option<Structure>,
2999}
3000
3001impl<'a> CustomDownstreamBuilder<'a> {
3002    fn new(structure: Structure) -> Self {
3003        skip_assert_initialized!();
3004        Self {
3005            builder: EventBuilder::new(),
3006            structure: Some(structure),
3007        }
3008    }
3009
3010    event_builder_generic_impl!(|s: &mut Self| {
3011        let structure = s.structure.take().unwrap();
3012        ffi::gst_event_new_custom(ffi::GST_EVENT_CUSTOM_DOWNSTREAM, structure.into_glib_ptr())
3013    });
3014}
3015
3016#[must_use = "The builder must be built to be used"]
3017pub struct CustomDownstreamOobBuilder<'a> {
3018    builder: EventBuilder<'a>,
3019    structure: Option<Structure>,
3020}
3021
3022impl<'a> CustomDownstreamOobBuilder<'a> {
3023    fn new(structure: Structure) -> Self {
3024        skip_assert_initialized!();
3025        Self {
3026            builder: EventBuilder::new(),
3027            structure: Some(structure),
3028        }
3029    }
3030
3031    event_builder_generic_impl!(|s: &mut Self| {
3032        let structure = s.structure.take().unwrap();
3033        ffi::gst_event_new_custom(
3034            ffi::GST_EVENT_CUSTOM_DOWNSTREAM_OOB,
3035            structure.into_glib_ptr(),
3036        )
3037    });
3038}
3039
3040#[must_use = "The builder must be built to be used"]
3041pub struct CustomDownstreamStickyBuilder<'a> {
3042    builder: EventBuilder<'a>,
3043    structure: Option<Structure>,
3044}
3045
3046impl<'a> CustomDownstreamStickyBuilder<'a> {
3047    fn new(structure: Structure) -> Self {
3048        skip_assert_initialized!();
3049        Self {
3050            builder: EventBuilder::new(),
3051            structure: Some(structure),
3052        }
3053    }
3054
3055    event_builder_generic_impl!(|s: &mut Self| {
3056        let structure = s.structure.take().unwrap();
3057        ffi::gst_event_new_custom(
3058            ffi::GST_EVENT_CUSTOM_DOWNSTREAM_STICKY,
3059            structure.into_glib_ptr(),
3060        )
3061    });
3062}
3063
3064#[must_use = "The builder must be built to be used"]
3065pub struct CustomBothBuilder<'a> {
3066    builder: EventBuilder<'a>,
3067    structure: Option<Structure>,
3068}
3069
3070impl<'a> CustomBothBuilder<'a> {
3071    fn new(structure: Structure) -> Self {
3072        skip_assert_initialized!();
3073        Self {
3074            builder: EventBuilder::new(),
3075            structure: Some(structure),
3076        }
3077    }
3078
3079    event_builder_generic_impl!(|s: &mut Self| {
3080        let structure = s.structure.take().unwrap();
3081        ffi::gst_event_new_custom(ffi::GST_EVENT_CUSTOM_BOTH, structure.into_glib_ptr())
3082    });
3083}
3084
3085#[must_use = "The builder must be built to be used"]
3086pub struct CustomBothOobBuilder<'a> {
3087    builder: EventBuilder<'a>,
3088    structure: Option<Structure>,
3089}
3090
3091impl<'a> CustomBothOobBuilder<'a> {
3092    fn new(structure: Structure) -> Self {
3093        skip_assert_initialized!();
3094        Self {
3095            builder: EventBuilder::new(),
3096            structure: Some(structure),
3097        }
3098    }
3099
3100    event_builder_generic_impl!(|s: &mut Self| {
3101        let structure = s.structure.take().unwrap();
3102        ffi::gst_event_new_custom(ffi::GST_EVENT_CUSTOM_BOTH_OOB, structure.into_glib_ptr())
3103    });
3104}
3105
3106#[cfg(test)]
3107mod tests {
3108    use super::*;
3109
3110    #[test]
3111    #[allow(deprecated)]
3112    fn test_simple() {
3113        crate::init().unwrap();
3114
3115        // Event without arguments
3116        let flush_start_evt = FlushStart::new();
3117        match flush_start_evt.view() {
3118            EventView::FlushStart(flush_start_evt) => {
3119                assert!(!flush_start_evt.is_sticky());
3120                assert!(flush_start_evt.structure().is_none());
3121            }
3122            _ => panic!("flush_start_evt.view() is not an EventView::FlushStart(_)"),
3123        }
3124
3125        let flush_start_evt = FlushStart::builder()
3126            .other_field("extra-field", true)
3127            .build();
3128        match flush_start_evt.view() {
3129            EventView::FlushStart(flush_start_evt) => {
3130                assert!(flush_start_evt.structure().is_some());
3131                if let Some(other_fields) = flush_start_evt.structure() {
3132                    assert!(other_fields.has_field("extra-field"));
3133                }
3134            }
3135            _ => panic!("flush_start_evt.view() is not an EventView::FlushStart(_)"),
3136        }
3137
3138        // Event with arguments
3139        let flush_stop_evt = FlushStop::builder(true)
3140            .other_field("extra-field", true)
3141            .build();
3142        match flush_stop_evt.view() {
3143            EventView::FlushStop(flush_stop_evt) => {
3144                assert!(flush_stop_evt.resets_time());
3145                assert!(flush_stop_evt.structure().is_some());
3146                if let Some(other_fields) = flush_stop_evt.structure() {
3147                    assert!(other_fields.has_field("extra-field"));
3148                }
3149            }
3150            _ => panic!("flush_stop_evt.view() is not an EventView::FlushStop(_)"),
3151        }
3152    }
3153
3154    #[test]
3155    fn test_get_structure_mut() {
3156        crate::init().unwrap();
3157
3158        let mut flush_start_evt = FlushStart::new();
3159
3160        {
3161            let flush_start_evt = flush_start_evt.get_mut().unwrap();
3162            let structure = flush_start_evt.structure_mut();
3163            structure.set("test", 42u32);
3164        }
3165
3166        let structure = flush_start_evt.structure().unwrap();
3167        assert_eq!(structure.get("test"), Ok(42u32));
3168    }
3169
3170    #[test]
3171    fn test_view_lifetimes() {
3172        crate::init().unwrap();
3173
3174        let caps = crate::Caps::builder("some/x-caps").build();
3175        let event = crate::event::Caps::new(&caps);
3176
3177        let caps2 = match event.view() {
3178            EventView::Caps(caps) => caps.caps(),
3179            _ => unreachable!(),
3180        };
3181
3182        assert_eq!(&*caps, caps2);
3183    }
3184
3185    #[test]
3186    fn test_select_streams() {
3187        crate::init().unwrap();
3188
3189        let s = ["foo", "bar"].to_vec();
3190        let event = crate::event::SelectStreams::new(s.iter().copied());
3191        let streams = match event.view() {
3192            EventView::SelectStreams(streams) => streams.streams(),
3193            _ => unreachable!(),
3194        };
3195        assert_eq!(streams.iter().collect::<Vec<_>>(), s);
3196    }
3197
3198    #[test]
3199    fn debug_impl() {
3200        use crate::format::{self, BytesFormatConstructor, ClockTime};
3201
3202        crate::init().unwrap();
3203
3204        // No formatted values as structure fields, caps inlined
3205        let mut evt = Caps::new(&crate::Caps::new_empty_simple("text/utf-8"));
3206        println!("{evt:?}");
3207
3208        {
3209            let evt = evt.make_mut();
3210            evt.structure_mut().set("user-defined", "my value");
3211        }
3212        let debug = format!("{evt:?}");
3213        println!("{debug}");
3214        assert!(debug.contains("my value"));
3215
3216        // No formatted values as structure fields, Segment is a structure field
3217        let mut evt = Segment::new(&crate::FormattedSegment::<format::Time>::new());
3218        println!("{evt:?}");
3219
3220        {
3221            let evt = evt.make_mut();
3222            evt.structure_mut().set("user-defined", "my value");
3223        }
3224        let debug = format!("{evt:?}");
3225        println!("{debug}");
3226        assert!(debug.contains("my value"));
3227
3228        // One formatted value as structure fields: position
3229        let mut evt = SegmentDone::new(ClockTime::from_mseconds(90_000));
3230        let debug = format!("{evt:?}");
3231        println!("{debug}");
3232        assert!(!debug.contains("format"));
3233
3234        {
3235            let evt = evt.make_mut();
3236            evt.structure_mut().set("user-defined", "my value");
3237        }
3238        let debug = format!("{evt:?}");
3239        println!("{debug}");
3240        assert!(debug.contains("my value"));
3241        assert!(!debug.contains("format"));
3242
3243        // Two formatted values as structure fields with the same format: minsize, maxsize
3244        let mut evt = Buffersize::new::<format::Bytes>(42.kibibytes(), 42.mebibytes(), false);
3245        let debug = format!("{evt:?}");
3246        println!("{debug}");
3247        assert!(!debug.contains("format"));
3248
3249        {
3250            let evt = evt.make_mut();
3251            evt.structure_mut().set("user-defined", "my value");
3252        }
3253        let debug = format!("{evt:?}");
3254        println!("{debug}");
3255        assert!(debug.contains("my value"));
3256        assert!(!debug.contains("format"));
3257    }
3258}