Skip to main content

gstreamer_play/
play_message.rs

1use crate::{Play, PlayMediaInfo, PlayMessageType, PlayState};
2
3#[derive(Debug)]
4#[non_exhaustive]
5#[doc(alias = "GstPlayMessage")]
6pub enum PlayMessage<'a> {
7    #[doc(alias = "GST_PLAY_MESSAGE_URI_LOADED")]
8    UriLoaded(&'a UriLoaded),
9    #[doc(alias = "GST_PLAY_MESSAGE_POSITION_UPDATED")]
10    PositionUpdated(&'a PositionUpdated),
11    #[doc(alias = "GST_PLAY_MESSAGE_DURATION_CHANGED")]
12    DurationChanged(&'a DurationChanged),
13    #[doc(alias = "GST_PLAY_MESSAGE_STATE_CHANGED")]
14    StateChanged(&'a StateChanged),
15    #[doc(alias = "GST_PLAY_MESSAGE_BUFFERING")]
16    Buffering(&'a Buffering),
17    #[doc(alias = "GST_PLAY_MESSAGE_END_OF_STREAM")]
18    EndOfStream(&'a EndOfStream),
19    #[doc(alias = "GST_PLAY_MESSAGE_ERROR")]
20    Error(&'a Error),
21    #[doc(alias = "GST_PLAY_MESSAGE_WARNING")]
22    Warning(&'a Warning),
23    #[doc(alias = "GST_PLAY_MESSAGE_VIDEO_DIMENSIONS_CHANGED")]
24    VideoDimensionsChanged(&'a VideoDimensionsChanged),
25    #[doc(alias = "GST_PLAY_MESSAGE_MEDIA_INFO_UPDATED")]
26    MediaInfoUpdated(&'a MediaInfoUpdated),
27    #[doc(alias = "GST_PLAY_MESSAGE_VOLUME_CHANGED")]
28    VolumeChanged(&'a VolumeChanged),
29    #[doc(alias = "GST_PLAY_MESSAGE_MUTE_CHANGED")]
30    MuteChanged(&'a MuteChanged),
31    #[doc(alias = "GST_PLAY_MESSAGE_SEEK_DONE")]
32    SeekDone(&'a SeekDone),
33    #[cfg(feature = "v1_30")]
34    #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
35    #[doc(alias = "GST_PLAY_MESSAGE_TRACKS_SELECTED")]
36    TracksSelected(&'a TracksSelected),
37    Other(&'a Other),
38}
39
40macro_rules! declare_concrete_message(
41    ($name:ident) => {
42        #[repr(transparent)]
43        pub struct $name<T = gst::MessageRef>(T);
44
45        impl $name {
46            #[inline]
47            pub fn message(&self) -> &gst::MessageRef {
48                unsafe { &*(self as *const Self as *const gst::MessageRef) }
49            }
50
51            #[inline]
52            unsafe fn view(message: &gst::MessageRef) -> PlayMessage<'_> { unsafe {
53                let message = &*(message as *const gst::MessageRef as *const Self);
54                PlayMessage::$name(message)
55            }}
56        }
57
58        impl std::ops::Deref for $name {
59            type Target = gst::MessageRef;
60
61            #[inline]
62            fn deref(&self) -> &Self::Target {
63                unsafe {
64                    &*(self as *const Self as *const Self::Target)
65                }
66            }
67        }
68
69        impl ToOwned for $name {
70            type Owned = $name<gst::Message>;
71
72            #[inline]
73            fn to_owned(&self) -> Self::Owned {
74                $name::<gst::Message>(self.copy())
75            }
76        }
77
78        impl std::ops::Deref for $name<gst::Message> {
79            type Target = $name;
80
81            #[inline]
82            fn deref(&self) -> &Self::Target {
83                unsafe { &*(self.0.as_ptr() as *const Self::Target) }
84            }
85        }
86
87        impl std::borrow::Borrow<$name> for $name<gst::Message> {
88            #[inline]
89            fn borrow(&self) -> &$name {
90                &*self
91            }
92        }
93
94        impl From<$name<gst::Message>> for gst::Message {
95            #[inline]
96            fn from(concrete: $name<gst::Message>) -> Self {
97                skip_assert_initialized!();
98                concrete.0
99            }
100        }
101    }
102);
103
104declare_concrete_message!(UriLoaded);
105impl UriLoaded {
106    pub fn uri(&self) -> &glib::GStr {
107        self.message().structure().unwrap().get("uri").unwrap()
108    }
109}
110impl std::fmt::Debug for UriLoaded {
111    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112        f.debug_struct("UriLoaded")
113            .field("structure", &self.message().structure())
114            .field("uri", &self.uri())
115            .finish()
116    }
117}
118
119declare_concrete_message!(PositionUpdated);
120impl PositionUpdated {
121    pub fn position(&self) -> Option<gst::ClockTime> {
122        self.message().structure().unwrap().get("position").unwrap()
123    }
124
125    #[cfg(feature = "v1_26")]
126    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
127    #[doc(alias = "gst_play_message_get_uri")]
128    pub fn uri(&self) -> glib::GString {
129        use crate::ffi;
130        use glib::translate::*;
131
132        assert_initialized_main_thread!();
133        unsafe {
134            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
135                self.message().as_ptr(),
136            )))
137        }
138    }
139}
140impl std::fmt::Debug for PositionUpdated {
141    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
142        f.debug_struct("PositionUpdated")
143            .field("structure", &self.message().structure())
144            .field("position", &self.position())
145            .finish()
146    }
147}
148
149declare_concrete_message!(DurationChanged);
150impl DurationChanged {
151    pub fn duration(&self) -> Option<gst::ClockTime> {
152        self.message().structure().unwrap().get("duration").unwrap()
153    }
154
155    #[cfg(feature = "v1_26")]
156    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
157    #[doc(alias = "gst_play_message_get_uri")]
158    pub fn uri(&self) -> glib::GString {
159        use crate::ffi;
160        use glib::translate::*;
161
162        assert_initialized_main_thread!();
163        unsafe {
164            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
165                self.message().as_ptr(),
166            )))
167        }
168    }
169}
170impl std::fmt::Debug for DurationChanged {
171    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
172        f.debug_struct("DurationChanged")
173            .field("structure", &self.message().structure())
174            .field("duration", &self.duration())
175            .finish()
176    }
177}
178
179declare_concrete_message!(StateChanged);
180impl StateChanged {
181    pub fn state(&self) -> PlayState {
182        self.message()
183            .structure()
184            .unwrap()
185            .get("play-state")
186            .unwrap()
187    }
188
189    #[cfg(feature = "v1_26")]
190    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
191    #[doc(alias = "gst_play_message_get_uri")]
192    pub fn uri(&self) -> glib::GString {
193        use crate::ffi;
194        use glib::translate::*;
195
196        assert_initialized_main_thread!();
197        unsafe {
198            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
199                self.message().as_ptr(),
200            )))
201        }
202    }
203}
204impl std::fmt::Debug for StateChanged {
205    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
206        f.debug_struct("StateChanged")
207            .field("structure", &self.message().structure())
208            .field("state", &self.state())
209            .finish()
210    }
211}
212
213declare_concrete_message!(Buffering);
214impl Buffering {
215    pub fn percent(&self) -> u32 {
216        self.message()
217            .structure()
218            .unwrap()
219            // Typo in the library
220            .get("bufferring-percent")
221            .unwrap()
222    }
223
224    #[cfg(feature = "v1_26")]
225    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
226    #[doc(alias = "gst_play_message_get_uri")]
227    pub fn uri(&self) -> glib::GString {
228        use crate::ffi;
229        use glib::translate::*;
230
231        assert_initialized_main_thread!();
232        unsafe {
233            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
234                self.message().as_ptr(),
235            )))
236        }
237    }
238}
239impl std::fmt::Debug for Buffering {
240    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
241        f.debug_struct("Buffering")
242            .field("structure", &self.message().structure())
243            .field("percent", &self.percent())
244            .finish()
245    }
246}
247
248declare_concrete_message!(EndOfStream);
249impl std::fmt::Debug for EndOfStream {
250    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
251        f.debug_struct("EndOfStream")
252            .field("structure", &self.message().structure())
253            .finish()
254    }
255}
256
257declare_concrete_message!(Error);
258impl Error {
259    pub fn error(&self) -> &glib::Error {
260        self.message().structure().unwrap().get("error").unwrap()
261    }
262
263    pub fn details(&self) -> Option<&gst::StructureRef> {
264        self.message()
265            .structure()
266            .unwrap()
267            .get_optional("error-details")
268            .unwrap()
269    }
270
271    #[cfg(feature = "v1_26")]
272    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
273    #[doc(alias = "gst_play_message_get_uri")]
274    pub fn uri(&self) -> glib::GString {
275        use crate::ffi;
276        use glib::translate::*;
277
278        assert_initialized_main_thread!();
279        unsafe {
280            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
281                self.message().as_ptr(),
282            )))
283        }
284    }
285
286    #[cfg(feature = "v1_26")]
287    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
288    #[doc(alias = "gst_play_message_get_stream_id")]
289    pub fn stream_id(&self) -> Option<glib::GString> {
290        use crate::ffi;
291        use glib::translate::*;
292
293        assert_initialized_main_thread!();
294        unsafe {
295            from_glib_none(ffi::gst_play_message_get_stream_id(mut_override(
296                self.message().as_ptr(),
297            )))
298        }
299    }
300
301    #[cfg(feature = "v1_26")]
302    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
303    #[doc(alias = "gst_play_message_parse_error_missing_plugin")]
304    pub fn missing_plugin(&self) -> Option<Vec<(glib::GString, glib::GString)>> {
305        use crate::ffi;
306        use glib::translate::*;
307
308        assert_initialized_main_thread!();
309        unsafe {
310            let mut descriptions = std::ptr::null_mut();
311            let mut installer_details = std::ptr::null_mut();
312            let ret = from_glib(ffi::gst_play_message_parse_error_missing_plugin(
313                mut_override(self.message().as_ptr()),
314                &mut descriptions,
315                &mut installer_details,
316            ));
317            if ret {
318                let mut ret = Vec::new();
319                for idx in 0.. {
320                    let description = *descriptions.add(idx);
321                    let installer_detail = *installer_details.add(idx);
322
323                    if description.is_null() {
324                        assert!(installer_detail.is_null());
325                        break;
326                    }
327
328                    ret.push((
329                        glib::GString::from_glib_full(description),
330                        glib::GString::from_glib_full(installer_detail),
331                    ));
332                }
333                glib::ffi::g_free(descriptions as glib::ffi::gpointer);
334                glib::ffi::g_free(installer_details as glib::ffi::gpointer);
335
336                Some(ret)
337            } else {
338                None
339            }
340        }
341    }
342}
343impl std::fmt::Debug for Error {
344    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
345        f.debug_struct("Error")
346            .field("structure", &self.message().structure())
347            .field("error", &self.error())
348            .field("details", &self.details())
349            .finish()
350    }
351}
352
353declare_concrete_message!(Warning);
354impl Warning {
355    pub fn error(&self) -> &glib::Error {
356        self.message().structure().unwrap().get("warning").unwrap()
357    }
358
359    pub fn details(&self) -> Option<&gst::StructureRef> {
360        self.message()
361            .structure()
362            .unwrap()
363            .get_optional("warning-details")
364            .unwrap()
365    }
366
367    #[cfg(feature = "v1_26")]
368    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
369    #[doc(alias = "gst_play_message_get_uri")]
370    pub fn uri(&self) -> glib::GString {
371        use crate::ffi;
372        use glib::translate::*;
373
374        assert_initialized_main_thread!();
375        unsafe {
376            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
377                self.message().as_ptr(),
378            )))
379        }
380    }
381
382    #[cfg(feature = "v1_26")]
383    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
384    #[doc(alias = "gst_play_message_get_stream_id")]
385    pub fn stream_id(&self) -> Option<glib::GString> {
386        use crate::ffi;
387        use glib::translate::*;
388
389        assert_initialized_main_thread!();
390        unsafe {
391            from_glib_none(ffi::gst_play_message_get_stream_id(mut_override(
392                self.message().as_ptr(),
393            )))
394        }
395    }
396
397    #[cfg(feature = "v1_26")]
398    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
399    #[doc(alias = "gst_play_message_parse_warning_missing_plugin")]
400    pub fn missing_plugin(&self) -> Option<Vec<(glib::GString, glib::GString)>> {
401        use crate::ffi;
402        use glib::translate::*;
403
404        assert_initialized_main_thread!();
405        unsafe {
406            let mut descriptions = std::ptr::null_mut();
407            let mut installer_details = std::ptr::null_mut();
408            let ret = from_glib(ffi::gst_play_message_parse_warning_missing_plugin(
409                mut_override(self.message().as_ptr()),
410                &mut descriptions,
411                &mut installer_details,
412            ));
413            if ret {
414                let mut ret = Vec::new();
415                for idx in 0.. {
416                    let description = *descriptions.add(idx);
417                    let installer_detail = *installer_details.add(idx);
418
419                    if description.is_null() {
420                        assert!(installer_detail.is_null());
421                        break;
422                    }
423
424                    ret.push((
425                        glib::GString::from_glib_full(description),
426                        glib::GString::from_glib_full(installer_detail),
427                    ));
428                }
429                glib::ffi::g_free(descriptions as glib::ffi::gpointer);
430                glib::ffi::g_free(installer_details as glib::ffi::gpointer);
431
432                Some(ret)
433            } else {
434                None
435            }
436        }
437    }
438}
439impl std::fmt::Debug for Warning {
440    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
441        f.debug_struct("Warning")
442            .field("structure", &self.message().structure())
443            .field("error", &self.error())
444            .field("details", &self.details())
445            .finish()
446    }
447}
448
449declare_concrete_message!(VideoDimensionsChanged);
450impl VideoDimensionsChanged {
451    pub fn width(&self) -> u32 {
452        self.message()
453            .structure()
454            .unwrap()
455            .get("video-width")
456            .unwrap()
457    }
458
459    pub fn height(&self) -> u32 {
460        self.message()
461            .structure()
462            .unwrap()
463            .get("video-height")
464            .unwrap()
465    }
466
467    #[cfg(feature = "v1_26")]
468    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
469    #[doc(alias = "gst_play_message_get_uri")]
470    pub fn uri(&self) -> glib::GString {
471        use crate::ffi;
472        use glib::translate::*;
473
474        assert_initialized_main_thread!();
475        unsafe {
476            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
477                self.message().as_ptr(),
478            )))
479        }
480    }
481}
482impl std::fmt::Debug for VideoDimensionsChanged {
483    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
484        f.debug_struct("VideoDimensionsChanged")
485            .field("structure", &self.message().structure())
486            .field("width", &self.width())
487            .field("height", &self.height())
488            .finish()
489    }
490}
491
492declare_concrete_message!(MediaInfoUpdated);
493impl MediaInfoUpdated {
494    pub fn media_info(&self) -> &PlayMediaInfo {
495        self.message()
496            .structure()
497            .unwrap()
498            .get("media-info")
499            .unwrap()
500    }
501
502    #[cfg(feature = "v1_26")]
503    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
504    #[doc(alias = "gst_play_message_get_uri")]
505    pub fn uri(&self) -> glib::GString {
506        use crate::ffi;
507        use glib::translate::*;
508
509        assert_initialized_main_thread!();
510        unsafe {
511            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
512                self.message().as_ptr(),
513            )))
514        }
515    }
516}
517impl std::fmt::Debug for MediaInfoUpdated {
518    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
519        f.debug_struct("MediaInfoUpdated")
520            .field("structure", &self.message().structure())
521            .field("media_info", &self.media_info())
522            .finish()
523    }
524}
525
526declare_concrete_message!(VolumeChanged);
527impl VolumeChanged {
528    pub fn volume(&self) -> f64 {
529        self.message().structure().unwrap().get("volume").unwrap()
530    }
531
532    #[cfg(feature = "v1_26")]
533    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
534    #[doc(alias = "gst_play_message_get_uri")]
535    pub fn uri(&self) -> glib::GString {
536        use crate::ffi;
537        use glib::translate::*;
538
539        assert_initialized_main_thread!();
540        unsafe {
541            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
542                self.message().as_ptr(),
543            )))
544        }
545    }
546}
547impl std::fmt::Debug for VolumeChanged {
548    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
549        f.debug_struct("VolumeChanged")
550            .field("structure", &self.message().structure())
551            .field("volume", &self.volume())
552            .finish()
553    }
554}
555
556declare_concrete_message!(MuteChanged);
557impl MuteChanged {
558    pub fn is_muted(&self) -> bool {
559        self.message().structure().unwrap().get("is-muted").unwrap()
560    }
561
562    #[cfg(feature = "v1_26")]
563    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
564    #[doc(alias = "gst_play_message_get_uri")]
565    pub fn uri(&self) -> glib::GString {
566        use crate::ffi;
567        use glib::translate::*;
568
569        assert_initialized_main_thread!();
570        unsafe {
571            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
572                self.message().as_ptr(),
573            )))
574        }
575    }
576}
577impl std::fmt::Debug for MuteChanged {
578    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
579        f.debug_struct("MuteChanged")
580            .field("structure", &self.message().structure())
581            .field("is_muted", &self.is_muted())
582            .finish()
583    }
584}
585
586declare_concrete_message!(SeekDone);
587impl SeekDone {
588    pub fn position(&self) -> Option<gst::ClockTime> {
589        self.message().structure().unwrap().get("position").unwrap()
590    }
591
592    #[cfg(feature = "v1_26")]
593    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
594    #[doc(alias = "gst_play_message_get_uri")]
595    pub fn uri(&self) -> glib::GString {
596        use crate::ffi;
597        use glib::translate::*;
598
599        assert_initialized_main_thread!();
600        unsafe {
601            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
602                self.message().as_ptr(),
603            )))
604        }
605    }
606}
607impl std::fmt::Debug for SeekDone {
608    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
609        f.debug_struct("SeekDone")
610            .field("structure", &self.message().structure())
611            .field("position", &self.position())
612            .finish()
613    }
614}
615
616#[cfg(feature = "v1_30")]
617#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
618declare_concrete_message!(TracksSelected);
619#[cfg(feature = "v1_30")]
620#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
621impl TracksSelected {
622    #[doc(alias = "gst_play_message_parse_tracks_selected")]
623    pub fn audio_track_id(&self) -> Option<glib::GString> {
624        use crate::ffi;
625        use glib::translate::*;
626        use std::ptr;
627
628        assert_initialized_main_thread!();
629        unsafe {
630            let mut id = ptr::null_mut();
631            ffi::gst_play_message_parse_tracks_selected(
632                mut_override(self.message().as_ptr()),
633                &mut id,
634                ptr::null_mut(),
635                ptr::null_mut(),
636            );
637
638            from_glib_full(id)
639        }
640    }
641
642    #[doc(alias = "gst_play_message_parse_tracks_selected")]
643    pub fn video_track_id(&self) -> Option<glib::GString> {
644        use crate::ffi;
645        use glib::translate::*;
646        use std::ptr;
647
648        assert_initialized_main_thread!();
649        unsafe {
650            let mut id = ptr::null_mut();
651            ffi::gst_play_message_parse_tracks_selected(
652                mut_override(self.message().as_ptr()),
653                ptr::null_mut(),
654                &mut id,
655                ptr::null_mut(),
656            );
657
658            from_glib_full(id)
659        }
660    }
661
662    #[doc(alias = "gst_play_message_parse_tracks_selected")]
663    pub fn subtitle_track_id(&self) -> Option<glib::GString> {
664        use crate::ffi;
665        use glib::translate::*;
666        use std::ptr;
667
668        assert_initialized_main_thread!();
669        unsafe {
670            let mut id = ptr::null_mut();
671            ffi::gst_play_message_parse_tracks_selected(
672                mut_override(self.message().as_ptr()),
673                ptr::null_mut(),
674                ptr::null_mut(),
675                &mut id,
676            );
677
678            from_glib_full(id)
679        }
680    }
681
682    #[doc(alias = "gst_play_message_get_uri")]
683    pub fn uri(&self) -> glib::GString {
684        use crate::ffi;
685        use glib::translate::*;
686
687        assert_initialized_main_thread!();
688        unsafe {
689            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
690                self.message().as_ptr(),
691            )))
692        }
693    }
694}
695#[cfg(feature = "v1_30")]
696#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
697impl std::fmt::Debug for TracksSelected {
698    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
699        f.debug_struct("TracksSelected")
700            .field("structure", &self.message().structure())
701            .field("audio_track_id", &self.audio_track_id())
702            .field("video_track_id", &self.video_track_id())
703            .field("subtitle_track_id", &self.subtitle_track_id())
704            .finish()
705    }
706}
707
708declare_concrete_message!(Other);
709
710impl Other {
711    #[cfg(feature = "v1_26")]
712    #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
713    #[doc(alias = "gst_play_message_get_uri")]
714    pub fn uri(&self) -> glib::GString {
715        use crate::ffi;
716        use glib::translate::*;
717
718        assert_initialized_main_thread!();
719        unsafe {
720            from_glib_none(ffi::gst_play_message_get_uri(mut_override(
721                self.message().as_ptr(),
722            )))
723        }
724    }
725}
726
727impl std::fmt::Debug for Other {
728    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
729        f.debug_struct("Other")
730            .field("structure", &self.message().structure())
731            .finish()
732    }
733}
734
735impl PlayMessage<'_> {
736    #[doc(alias = "gst_play_message_parse_uri_loaded")]
737    #[doc(alias = "gst_play_message_parse_position_updated")]
738    #[doc(alias = "gst_play_message_parse_duration_updated")]
739    #[doc(alias = "gst_play_message_parse_duration_changed")]
740    #[doc(alias = "gst_play_message_parse_state_changed")]
741    #[doc(alias = "gst_play_message_parse_buffering")]
742    #[doc(alias = "gst_play_message_parse_buffering_percent")]
743    #[doc(alias = "gst_play_message_parse_error")]
744    #[doc(alias = "gst_play_message_parse_warning")]
745    #[doc(alias = "gst_play_message_parse_video_dimensions_changed")]
746    #[doc(alias = "gst_play_message_parse_media_info_updated")]
747    #[doc(alias = "gst_play_message_parse_muted_changed")]
748    #[doc(alias = "gst_play_message_parse_volume_changed")]
749    #[doc(alias = "gst_play_message_parse_seek_done")]
750    pub fn parse(msg: &gst::Message) -> Result<PlayMessage<'_>, glib::error::BoolError> {
751        skip_assert_initialized!();
752
753        if !Play::is_play_message(msg) {
754            return Err(glib::bool_error!("Invalid play message"));
755        }
756
757        unsafe {
758            match PlayMessageType::parse_type(msg) {
759                PlayMessageType::UriLoaded => Ok(UriLoaded::view(msg)),
760                PlayMessageType::PositionUpdated => Ok(PositionUpdated::view(msg)),
761                PlayMessageType::DurationChanged => Ok(DurationChanged::view(msg)),
762                PlayMessageType::StateChanged => Ok(StateChanged::view(msg)),
763                PlayMessageType::Buffering => Ok(Buffering::view(msg)),
764                PlayMessageType::EndOfStream => Ok(EndOfStream::view(msg)),
765                PlayMessageType::Error => Ok(Error::view(msg)),
766                PlayMessageType::Warning => Ok(Warning::view(msg)),
767                PlayMessageType::VideoDimensionsChanged => Ok(VideoDimensionsChanged::view(msg)),
768                PlayMessageType::MediaInfoUpdated => Ok(MediaInfoUpdated::view(msg)),
769                PlayMessageType::VolumeChanged => Ok(VolumeChanged::view(msg)),
770                PlayMessageType::MuteChanged => Ok(MuteChanged::view(msg)),
771                PlayMessageType::SeekDone => Ok(SeekDone::view(msg)),
772                #[cfg(feature = "v1_30")]
773                PlayMessageType::TracksSelected => Ok(TracksSelected::view(msg)),
774                _ => Ok(Other::view(msg)),
775            }
776        }
777    }
778}