gstreamer/
query.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{
4    borrow::{Borrow, BorrowMut},
5    ffi::CStr,
6    fmt, mem,
7    ops::{Deref, DerefMut},
8    ptr,
9};
10
11use glib::{object::IsA, translate::*};
12use smallvec::SmallVec;
13
14use crate::{
15    ffi,
16    format::{CompatibleFormattedValue, FormattedValue, GenericFormattedValue},
17    structure::*,
18};
19
20mini_object_wrapper!(Query, QueryRef, ffi::GstQuery, || {
21    ffi::gst_query_get_type()
22});
23
24impl QueryRef {
25    #[doc(alias = "get_structure")]
26    #[doc(alias = "gst_query_get_structure")]
27    #[inline]
28    pub fn structure(&self) -> Option<&StructureRef> {
29        unsafe {
30            let structure = ffi::gst_query_get_structure(self.as_mut_ptr());
31            if structure.is_null() {
32                None
33            } else {
34                Some(StructureRef::from_glib_borrow(structure))
35            }
36        }
37    }
38
39    #[doc(alias = "get_mut_structure")]
40    #[doc(alias = "gst_query_writable_structure")]
41    #[inline]
42    pub fn structure_mut(&mut self) -> &mut StructureRef {
43        unsafe {
44            let structure = ffi::gst_query_writable_structure(self.as_mut_ptr());
45            StructureRef::from_glib_borrow_mut(structure)
46        }
47    }
48
49    #[doc(alias = "GST_QUERY_IS_DOWNSTREAM")]
50    #[inline]
51    pub fn is_downstream(&self) -> bool {
52        unsafe { ((*self.as_ptr()).type_ as u32) & ffi::GST_QUERY_TYPE_DOWNSTREAM != 0 }
53    }
54
55    #[doc(alias = "GST_QUERY_IS_UPSTREAM")]
56    #[inline]
57    pub fn is_upstream(&self) -> bool {
58        unsafe { ((*self.as_ptr()).type_ as u32) & ffi::GST_QUERY_TYPE_UPSTREAM != 0 }
59    }
60
61    #[doc(alias = "GST_QUERY_IS_SERIALIZED")]
62    #[inline]
63    pub fn is_serialized(&self) -> bool {
64        unsafe { ((*self.as_ptr()).type_ as u32) & ffi::GST_QUERY_TYPE_SERIALIZED != 0 }
65    }
66
67    pub fn view(&self) -> QueryView {
68        unsafe {
69            let type_ = (*self.as_ptr()).type_;
70
71            match type_ {
72                ffi::GST_QUERY_POSITION => Position::view(self),
73                ffi::GST_QUERY_DURATION => Duration::view(self),
74                ffi::GST_QUERY_LATENCY => Latency::view(self),
75                ffi::GST_QUERY_SEEKING => Seeking::view(self),
76                ffi::GST_QUERY_SEGMENT => Segment::view(self),
77                ffi::GST_QUERY_CONVERT => Convert::view(self),
78                ffi::GST_QUERY_FORMATS => Formats::view(self),
79                ffi::GST_QUERY_BUFFERING => Buffering::view(self),
80                ffi::GST_QUERY_CUSTOM => Custom::view(self),
81                ffi::GST_QUERY_URI => Uri::view(self),
82                ffi::GST_QUERY_ALLOCATION => Allocation::view(self),
83                ffi::GST_QUERY_SCHEDULING => Scheduling::view(self),
84                ffi::GST_QUERY_ACCEPT_CAPS => AcceptCaps::view(self),
85                ffi::GST_QUERY_CAPS => Caps::view(self),
86                ffi::GST_QUERY_DRAIN => Drain::view(self),
87                ffi::GST_QUERY_CONTEXT => Context::view(self),
88                #[cfg(feature = "v1_16")]
89                ffi::GST_QUERY_BITRATE => Bitrate::view(self),
90                #[cfg(feature = "v1_22")]
91                ffi::GST_QUERY_SELECTABLE => Selectable::view(self),
92                _ => Other::view(self),
93            }
94        }
95    }
96
97    pub fn view_mut(&mut self) -> QueryViewMut {
98        unsafe {
99            let type_ = (*self.as_ptr()).type_;
100
101            match type_ {
102                ffi::GST_QUERY_POSITION => Position::view_mut(self),
103                ffi::GST_QUERY_DURATION => Duration::view_mut(self),
104                ffi::GST_QUERY_LATENCY => Latency::view_mut(self),
105                ffi::GST_QUERY_SEEKING => Seeking::view_mut(self),
106                ffi::GST_QUERY_SEGMENT => Segment::view_mut(self),
107                ffi::GST_QUERY_CONVERT => Convert::view_mut(self),
108                ffi::GST_QUERY_FORMATS => Formats::view_mut(self),
109                ffi::GST_QUERY_BUFFERING => Buffering::view_mut(self),
110                ffi::GST_QUERY_CUSTOM => Custom::view_mut(self),
111                ffi::GST_QUERY_URI => Uri::view_mut(self),
112                ffi::GST_QUERY_ALLOCATION => Allocation::view_mut(self),
113                ffi::GST_QUERY_SCHEDULING => Scheduling::view_mut(self),
114                ffi::GST_QUERY_ACCEPT_CAPS => AcceptCaps::view_mut(self),
115                ffi::GST_QUERY_CAPS => Caps::view_mut(self),
116                ffi::GST_QUERY_DRAIN => Drain::view_mut(self),
117                ffi::GST_QUERY_CONTEXT => Context::view_mut(self),
118                #[cfg(feature = "v1_16")]
119                ffi::GST_QUERY_BITRATE => Bitrate::view_mut(self),
120                #[cfg(feature = "v1_22")]
121                ffi::GST_QUERY_SELECTABLE => Selectable::view_mut(self),
122                _ => Other::view_mut(self),
123            }
124        }
125    }
126}
127
128impl fmt::Debug for Query {
129    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
130        QueryRef::fmt(self, f)
131    }
132}
133
134impl fmt::Debug for QueryRef {
135    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
136        f.debug_struct("Query")
137            .field("ptr", &self.as_ptr())
138            .field("type", &unsafe {
139                let type_ = ffi::gst_query_type_get_name((*self.as_ptr()).type_);
140                CStr::from_ptr(type_).to_str().unwrap()
141            })
142            .field("structure", &self.structure())
143            .finish()
144    }
145}
146
147#[derive(Debug)]
148#[non_exhaustive]
149pub enum QueryView<'a> {
150    Position(&'a Position),
151    Duration(&'a Duration),
152    Latency(&'a Latency),
153    Seeking(&'a Seeking),
154    Segment(&'a Segment),
155    Convert(&'a Convert),
156    Formats(&'a Formats),
157    Buffering(&'a Buffering),
158    Custom(&'a Custom),
159    Uri(&'a Uri),
160    Allocation(&'a Allocation),
161    Scheduling(&'a Scheduling),
162    AcceptCaps(&'a AcceptCaps),
163    Caps(&'a Caps),
164    Drain(&'a Drain),
165    Context(&'a Context),
166    #[cfg(feature = "v1_16")]
167    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
168    Bitrate(&'a Bitrate),
169    #[cfg(feature = "v1_22")]
170    #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
171    Selectable(&'a Selectable),
172    Other(&'a Other),
173}
174
175#[derive(Debug)]
176#[non_exhaustive]
177pub enum QueryViewMut<'a> {
178    Position(&'a mut Position),
179    Duration(&'a mut Duration),
180    Latency(&'a mut Latency),
181    Seeking(&'a mut Seeking),
182    Segment(&'a mut Segment),
183    Convert(&'a mut Convert),
184    Formats(&'a mut Formats),
185    Buffering(&'a mut Buffering),
186    Custom(&'a mut Custom),
187    Uri(&'a mut Uri),
188    Allocation(&'a mut Allocation),
189    Scheduling(&'a mut Scheduling),
190    AcceptCaps(&'a mut AcceptCaps),
191    Caps(&'a mut Caps),
192    Drain(&'a mut Drain),
193    Context(&'a mut Context),
194    #[cfg(feature = "v1_16")]
195    #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
196    Bitrate(&'a mut Bitrate),
197    #[cfg(feature = "v1_22")]
198    #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
199    Selectable(&'a mut Selectable),
200    Other(&'a mut Other),
201}
202
203macro_rules! declare_concrete_query(
204    ($name:ident, $param:ident) => {
205        #[repr(transparent)]
206        pub struct $name<$param = QueryRef>($param);
207
208        impl $name {
209            #[inline]
210            pub fn query(&self) -> &QueryRef {
211                unsafe { &*(self as *const Self as *const QueryRef) }
212            }
213
214            #[inline]
215            pub fn query_mut(&mut self) -> &mut QueryRef {
216                unsafe { &mut *(self as *mut Self as *mut QueryRef) }
217            }
218
219            #[inline]
220            unsafe fn view(query: &QueryRef) -> QueryView<'_> {
221                let query = &*(query as *const QueryRef as *const Self);
222                QueryView::$name(query)
223            }
224
225            #[inline]
226            unsafe fn view_mut(query: &mut QueryRef) -> QueryViewMut<'_> {
227                let query = &mut *(query as *mut QueryRef as *mut Self);
228                QueryViewMut::$name(query)
229            }
230        }
231
232        impl Deref for $name {
233            type Target = QueryRef;
234
235            #[inline]
236            fn deref(&self) -> &Self::Target {
237                self.query()
238            }
239        }
240
241        impl DerefMut for $name {
242            #[inline]
243            fn deref_mut(&mut self) -> &mut Self::Target {
244                self.query_mut()
245            }
246        }
247
248        impl ToOwned for $name {
249            type Owned = $name<Query>;
250
251            #[inline]
252            fn to_owned(&self) -> Self::Owned {
253                $name::<Query>(self.copy())
254            }
255        }
256
257        impl $name<Query> {
258            #[inline]
259            pub fn get_mut(&mut self) -> Option<&mut $name> {
260                self.0
261                    .get_mut()
262                    .map(|query| unsafe { &mut *(query as *mut QueryRef as *mut $name) })
263            }
264        }
265
266        impl Deref for $name<Query> {
267            type Target = $name;
268
269            #[inline]
270            fn deref(&self) -> &Self::Target {
271                unsafe { &*(self.0.as_ptr() as *const Self::Target) }
272            }
273        }
274
275        impl DerefMut for $name<Query> {
276            #[inline]
277            fn deref_mut(&mut self) -> &mut Self::Target {
278                debug_assert!(self.0.is_writable());
279                unsafe { &mut *(self.0.as_mut_ptr() as *mut Self::Target) }
280            }
281        }
282
283        impl Borrow<$name> for $name<Query> {
284            #[inline]
285            fn borrow(&self) -> &$name {
286                &*self
287            }
288        }
289
290        impl BorrowMut<$name> for $name<Query> {
291            #[inline]
292            fn borrow_mut(&mut self) -> &mut $name {
293                &mut *self
294            }
295        }
296
297        impl From<$name<Query>> for Query {
298            #[inline]
299            fn from(concrete: $name<Query>) -> Self {
300                skip_assert_initialized!();
301                concrete.0
302            }
303        }
304    }
305);
306
307declare_concrete_query!(Position, T);
308impl Position<Query> {
309    #[doc(alias = "gst_query_new_position")]
310    pub fn new(fmt: crate::Format) -> Self {
311        assert_initialized_main_thread!();
312        unsafe { Self(from_glib_full(ffi::gst_query_new_position(fmt.into_glib()))) }
313    }
314}
315
316impl Position {
317    #[doc(alias = "get_result")]
318    #[doc(alias = "gst_query_parse_position")]
319    pub fn result(&self) -> GenericFormattedValue {
320        unsafe {
321            let mut fmt = mem::MaybeUninit::uninit();
322            let mut pos = mem::MaybeUninit::uninit();
323
324            ffi::gst_query_parse_position(self.as_mut_ptr(), fmt.as_mut_ptr(), pos.as_mut_ptr());
325
326            GenericFormattedValue::new(from_glib(fmt.assume_init()), pos.assume_init())
327        }
328    }
329
330    #[doc(alias = "get_format")]
331    #[doc(alias = "gst_query_parse_position")]
332    pub fn format(&self) -> crate::Format {
333        unsafe {
334            let mut fmt = mem::MaybeUninit::uninit();
335
336            ffi::gst_query_parse_position(self.as_mut_ptr(), fmt.as_mut_ptr(), ptr::null_mut());
337
338            from_glib(fmt.assume_init())
339        }
340    }
341
342    #[doc(alias = "gst_query_set_position")]
343    pub fn set(&mut self, pos: impl FormattedValue) {
344        assert_eq!(pos.format(), self.format());
345        unsafe {
346            ffi::gst_query_set_position(
347                self.as_mut_ptr(),
348                pos.format().into_glib(),
349                pos.into_raw_value(),
350            );
351        }
352    }
353}
354
355impl std::fmt::Debug for Position {
356    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
357        f.debug_struct("Position")
358            .field("structure", &self.query().structure())
359            .field("result", &self.result())
360            .field("format", &self.format())
361            .finish()
362    }
363}
364
365impl std::fmt::Debug for Position<Query> {
366    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367        Position::<QueryRef>::fmt(self, f)
368    }
369}
370
371declare_concrete_query!(Duration, T);
372impl Duration<Query> {
373    #[doc(alias = "gst_query_new_duration")]
374    pub fn new(fmt: crate::Format) -> Self {
375        assert_initialized_main_thread!();
376        unsafe { Self(from_glib_full(ffi::gst_query_new_duration(fmt.into_glib()))) }
377    }
378}
379
380impl Duration {
381    #[doc(alias = "get_result")]
382    #[doc(alias = "gst_query_parse_duration")]
383    pub fn result(&self) -> GenericFormattedValue {
384        unsafe {
385            let mut fmt = mem::MaybeUninit::uninit();
386            let mut pos = mem::MaybeUninit::uninit();
387
388            ffi::gst_query_parse_duration(self.as_mut_ptr(), fmt.as_mut_ptr(), pos.as_mut_ptr());
389
390            GenericFormattedValue::new(from_glib(fmt.assume_init()), pos.assume_init())
391        }
392    }
393
394    #[doc(alias = "get_format")]
395    #[doc(alias = "gst_query_parse_duration")]
396    pub fn format(&self) -> crate::Format {
397        unsafe {
398            let mut fmt = mem::MaybeUninit::uninit();
399
400            ffi::gst_query_parse_duration(self.as_mut_ptr(), fmt.as_mut_ptr(), ptr::null_mut());
401
402            from_glib(fmt.assume_init())
403        }
404    }
405
406    #[doc(alias = "gst_query_set_duration")]
407    pub fn set(&mut self, dur: impl FormattedValue) {
408        assert_eq!(dur.format(), self.format());
409        unsafe {
410            ffi::gst_query_set_duration(
411                self.as_mut_ptr(),
412                dur.format().into_glib(),
413                dur.into_raw_value(),
414            );
415        }
416    }
417}
418
419impl std::fmt::Debug for Duration {
420    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
421        f.debug_struct("Duration")
422            .field("structure", &self.query().structure())
423            .field("result", &self.result())
424            .field("format", &self.format())
425            .finish()
426    }
427}
428
429impl std::fmt::Debug for Duration<Query> {
430    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
431        Duration::<QueryRef>::fmt(self, f)
432    }
433}
434
435declare_concrete_query!(Latency, T);
436impl Latency<Query> {
437    #[doc(alias = "gst_query_new_latency")]
438    pub fn new() -> Self {
439        assert_initialized_main_thread!();
440        unsafe { Self(from_glib_full(ffi::gst_query_new_latency())) }
441    }
442}
443
444impl Default for Latency<Query> {
445    fn default() -> Self {
446        Self::new()
447    }
448}
449
450impl Latency {
451    #[doc(alias = "get_result")]
452    #[doc(alias = "gst_query_parse_latency")]
453    pub fn result(&self) -> (bool, crate::ClockTime, Option<crate::ClockTime>) {
454        unsafe {
455            let mut live = mem::MaybeUninit::uninit();
456            let mut min = mem::MaybeUninit::uninit();
457            let mut max = mem::MaybeUninit::uninit();
458
459            ffi::gst_query_parse_latency(
460                self.as_mut_ptr(),
461                live.as_mut_ptr(),
462                min.as_mut_ptr(),
463                max.as_mut_ptr(),
464            );
465
466            (
467                from_glib(live.assume_init()),
468                try_from_glib(min.assume_init()).expect("undefined min latency"),
469                from_glib(max.assume_init()),
470            )
471        }
472    }
473
474    #[doc(alias = "gst_query_set_latency")]
475    pub fn set(
476        &mut self,
477        live: bool,
478        min: crate::ClockTime,
479        max: impl Into<Option<crate::ClockTime>>,
480    ) {
481        unsafe {
482            ffi::gst_query_set_latency(
483                self.as_mut_ptr(),
484                live.into_glib(),
485                min.into_glib(),
486                max.into().into_glib(),
487            );
488        }
489    }
490}
491
492impl std::fmt::Debug for Latency {
493    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
494        f.debug_struct("Latency")
495            .field("structure", &self.query().structure())
496            .field("result", &self.result())
497            .finish()
498    }
499}
500
501impl std::fmt::Debug for Latency<Query> {
502    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
503        Latency::<QueryRef>::fmt(self, f)
504    }
505}
506
507declare_concrete_query!(Seeking, T);
508impl Seeking<Query> {
509    #[doc(alias = "gst_query_new_seeking")]
510    pub fn new(fmt: crate::Format) -> Self {
511        assert_initialized_main_thread!();
512        unsafe { Self(from_glib_full(ffi::gst_query_new_seeking(fmt.into_glib()))) }
513    }
514}
515
516impl Seeking {
517    #[doc(alias = "get_result")]
518    #[doc(alias = "gst_query_parse_seeking")]
519    pub fn result(&self) -> (bool, GenericFormattedValue, GenericFormattedValue) {
520        unsafe {
521            let mut fmt = mem::MaybeUninit::uninit();
522            let mut seekable = mem::MaybeUninit::uninit();
523            let mut start = mem::MaybeUninit::uninit();
524            let mut end = mem::MaybeUninit::uninit();
525            ffi::gst_query_parse_seeking(
526                self.as_mut_ptr(),
527                fmt.as_mut_ptr(),
528                seekable.as_mut_ptr(),
529                start.as_mut_ptr(),
530                end.as_mut_ptr(),
531            );
532
533            (
534                from_glib(seekable.assume_init()),
535                GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
536                GenericFormattedValue::new(from_glib(fmt.assume_init()), end.assume_init()),
537            )
538        }
539    }
540
541    #[doc(alias = "get_format")]
542    #[doc(alias = "gst_query_parse_seeking")]
543    pub fn format(&self) -> crate::Format {
544        unsafe {
545            let mut fmt = mem::MaybeUninit::uninit();
546            ffi::gst_query_parse_seeking(
547                self.as_mut_ptr(),
548                fmt.as_mut_ptr(),
549                ptr::null_mut(),
550                ptr::null_mut(),
551                ptr::null_mut(),
552            );
553
554            from_glib(fmt.assume_init())
555        }
556    }
557
558    #[doc(alias = "gst_query_set_seeking")]
559    pub fn set<V: FormattedValue>(
560        &mut self,
561        seekable: bool,
562        start: V,
563        end: impl CompatibleFormattedValue<V>,
564    ) {
565        assert_eq!(self.format(), start.format());
566        let end = end.try_into_checked(start).unwrap();
567
568        unsafe {
569            ffi::gst_query_set_seeking(
570                self.as_mut_ptr(),
571                start.format().into_glib(),
572                seekable.into_glib(),
573                start.into_raw_value(),
574                end.into_raw_value(),
575            );
576        }
577    }
578}
579
580impl std::fmt::Debug for Seeking {
581    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
582        f.debug_struct("Seeking")
583            .field("structure", &self.query().structure())
584            .field("result", &self.result())
585            .field("format", &self.format())
586            .finish()
587    }
588}
589
590impl std::fmt::Debug for Seeking<Query> {
591    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
592        Seeking::<QueryRef>::fmt(self, f)
593    }
594}
595
596declare_concrete_query!(Segment, T);
597impl Segment<Query> {
598    #[doc(alias = "gst_query_new_segment")]
599    pub fn new(fmt: crate::Format) -> Self {
600        assert_initialized_main_thread!();
601        unsafe { Self(from_glib_full(ffi::gst_query_new_segment(fmt.into_glib()))) }
602    }
603}
604
605impl Segment {
606    #[doc(alias = "get_result")]
607    #[doc(alias = "gst_query_parse_segment")]
608    pub fn result(&self) -> (f64, GenericFormattedValue, GenericFormattedValue) {
609        unsafe {
610            let mut rate = mem::MaybeUninit::uninit();
611            let mut fmt = mem::MaybeUninit::uninit();
612            let mut start = mem::MaybeUninit::uninit();
613            let mut stop = mem::MaybeUninit::uninit();
614
615            ffi::gst_query_parse_segment(
616                self.as_mut_ptr(),
617                rate.as_mut_ptr(),
618                fmt.as_mut_ptr(),
619                start.as_mut_ptr(),
620                stop.as_mut_ptr(),
621            );
622            (
623                rate.assume_init(),
624                GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
625                GenericFormattedValue::new(from_glib(fmt.assume_init()), stop.assume_init()),
626            )
627        }
628    }
629
630    #[doc(alias = "get_format")]
631    #[doc(alias = "gst_query_parse_segment")]
632    pub fn format(&self) -> crate::Format {
633        unsafe {
634            let mut fmt = mem::MaybeUninit::uninit();
635
636            ffi::gst_query_parse_segment(
637                self.as_mut_ptr(),
638                ptr::null_mut(),
639                fmt.as_mut_ptr(),
640                ptr::null_mut(),
641                ptr::null_mut(),
642            );
643            from_glib(fmt.assume_init())
644        }
645    }
646
647    #[doc(alias = "gst_query_set_segment")]
648    pub fn set<V: FormattedValue>(
649        &mut self,
650        rate: f64,
651        start: V,
652        stop: impl CompatibleFormattedValue<V>,
653    ) {
654        let stop = stop.try_into_checked(start).unwrap();
655
656        unsafe {
657            ffi::gst_query_set_segment(
658                self.as_mut_ptr(),
659                rate,
660                start.format().into_glib(),
661                start.into_raw_value(),
662                stop.into_raw_value(),
663            );
664        }
665    }
666}
667
668impl std::fmt::Debug for Segment {
669    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
670        f.debug_struct("Segment")
671            .field("structure", &self.query().structure())
672            .field("result", &self.result())
673            .field("format", &self.format())
674            .finish()
675    }
676}
677
678impl std::fmt::Debug for Segment<Query> {
679    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
680        Segment::<QueryRef>::fmt(self, f)
681    }
682}
683
684declare_concrete_query!(Convert, T);
685impl Convert<Query> {
686    #[doc(alias = "gst_query_new_convert")]
687    pub fn new(value: impl FormattedValue, dest_fmt: crate::Format) -> Self {
688        assert_initialized_main_thread!();
689        unsafe {
690            Self(from_glib_full(ffi::gst_query_new_convert(
691                value.format().into_glib(),
692                value.into_raw_value(),
693                dest_fmt.into_glib(),
694            )))
695        }
696    }
697}
698
699impl Convert {
700    #[doc(alias = "get_result")]
701    #[doc(alias = "gst_query_parse_convert")]
702    pub fn result(&self) -> (GenericFormattedValue, GenericFormattedValue) {
703        unsafe {
704            let mut src_fmt = mem::MaybeUninit::uninit();
705            let mut src = mem::MaybeUninit::uninit();
706            let mut dest_fmt = mem::MaybeUninit::uninit();
707            let mut dest = mem::MaybeUninit::uninit();
708
709            ffi::gst_query_parse_convert(
710                self.as_mut_ptr(),
711                src_fmt.as_mut_ptr(),
712                src.as_mut_ptr(),
713                dest_fmt.as_mut_ptr(),
714                dest.as_mut_ptr(),
715            );
716            (
717                GenericFormattedValue::new(from_glib(src_fmt.assume_init()), src.assume_init()),
718                GenericFormattedValue::new(from_glib(dest_fmt.assume_init()), dest.assume_init()),
719            )
720        }
721    }
722
723    #[doc(alias = "gst_query_parse_convert")]
724    pub fn get(&self) -> (GenericFormattedValue, crate::Format) {
725        unsafe {
726            let mut src_fmt = mem::MaybeUninit::uninit();
727            let mut src = mem::MaybeUninit::uninit();
728            let mut dest_fmt = mem::MaybeUninit::uninit();
729
730            ffi::gst_query_parse_convert(
731                self.as_mut_ptr(),
732                src_fmt.as_mut_ptr(),
733                src.as_mut_ptr(),
734                dest_fmt.as_mut_ptr(),
735                ptr::null_mut(),
736            );
737            (
738                GenericFormattedValue::new(from_glib(src_fmt.assume_init()), src.assume_init()),
739                from_glib(dest_fmt.assume_init()),
740            )
741        }
742    }
743
744    #[doc(alias = "gst_query_set_convert")]
745    pub fn set(&mut self, src: impl FormattedValue, dest: impl FormattedValue) {
746        unsafe {
747            ffi::gst_query_set_convert(
748                self.as_mut_ptr(),
749                src.format().into_glib(),
750                src.into_raw_value(),
751                dest.format().into_glib(),
752                dest.into_raw_value(),
753            );
754        }
755    }
756}
757
758impl std::fmt::Debug for Convert {
759    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
760        let (source, dest) = self.result();
761
762        f.debug_struct("Convert")
763            .field("structure", &self.query().structure())
764            .field("source", &source)
765            .field("dest", &dest)
766            .finish()
767    }
768}
769
770impl std::fmt::Debug for Convert<Query> {
771    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
772        Convert::<QueryRef>::fmt(self, f)
773    }
774}
775
776declare_concrete_query!(Formats, T);
777impl Formats<Query> {
778    #[doc(alias = "gst_query_new_formats")]
779    pub fn new() -> Self {
780        assert_initialized_main_thread!();
781        unsafe { Self(from_glib_full(ffi::gst_query_new_formats())) }
782    }
783}
784
785impl Default for Formats<Query> {
786    fn default() -> Self {
787        Self::new()
788    }
789}
790
791impl Formats {
792    #[doc(alias = "get_result")]
793    #[doc(alias = "gst_query_parse_n_formats")]
794    #[doc(alias = "gst_query_parse_nth_format")]
795    pub fn result(&self) -> FormatsIter<'_> {
796        FormatsIter::new(self)
797    }
798
799    #[doc(alias = "gst_query_set_formats")]
800    #[doc(alias = "gst_query_set_formatsv")]
801    pub fn set(&mut self, formats: impl IntoIterator<Item = crate::Format>) {
802        unsafe {
803            let v = formats
804                .into_iter()
805                .map(|f| f.into_glib())
806                .collect::<SmallVec<[_; 8]>>();
807            ffi::gst_query_set_formatsv(self.as_mut_ptr(), v.len() as i32, v.as_ptr() as *mut _);
808        }
809    }
810}
811
812impl std::fmt::Debug for Formats {
813    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
814        struct FormatsDebug<'a>(&'a Formats);
815
816        impl std::fmt::Debug for FormatsDebug<'_> {
817            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
818                f.debug_list().entries(self.0.result()).finish()
819            }
820        }
821
822        f.debug_struct("Formats")
823            .field("structure", &self.query().structure())
824            .field("result", &FormatsDebug(self))
825            .finish()
826    }
827}
828
829impl std::fmt::Debug for Formats<Query> {
830    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
831        Formats::<QueryRef>::fmt(self, f)
832    }
833}
834
835crate::utils::define_fixed_size_iter!(
836    FormatsIter,
837    &'a Formats,
838    crate::Format,
839    |collection: &Formats| unsafe {
840        let mut n = mem::MaybeUninit::uninit();
841        ffi::gst_query_parse_n_formats(collection.as_mut_ptr(), n.as_mut_ptr());
842        n.assume_init() as usize
843    },
844    |collection: &Formats, idx: usize| unsafe {
845        let mut fmt = mem::MaybeUninit::uninit();
846        ffi::gst_query_parse_nth_format(collection.as_mut_ptr(), idx as u32, fmt.as_mut_ptr());
847        from_glib(fmt.assume_init())
848    }
849);
850
851declare_concrete_query!(Buffering, T);
852impl Buffering<Query> {
853    #[doc(alias = "gst_query_new_buffering")]
854    pub fn new(fmt: crate::Format) -> Self {
855        assert_initialized_main_thread!();
856        unsafe {
857            Self(from_glib_full(ffi::gst_query_new_buffering(
858                fmt.into_glib(),
859            )))
860        }
861    }
862}
863
864impl Buffering {
865    #[doc(alias = "get_format")]
866    #[doc(alias = "gst_query_parse_buffering_range")]
867    pub fn format(&self) -> crate::Format {
868        unsafe {
869            let mut fmt = mem::MaybeUninit::uninit();
870
871            ffi::gst_query_parse_buffering_range(
872                self.as_mut_ptr(),
873                fmt.as_mut_ptr(),
874                ptr::null_mut(),
875                ptr::null_mut(),
876                ptr::null_mut(),
877            );
878
879            from_glib(fmt.assume_init())
880        }
881    }
882
883    #[doc(alias = "get_percent")]
884    #[doc(alias = "gst_query_parse_buffering_percent")]
885    pub fn percent(&self) -> (bool, i32) {
886        unsafe {
887            let mut busy = mem::MaybeUninit::uninit();
888            let mut percent = mem::MaybeUninit::uninit();
889
890            ffi::gst_query_parse_buffering_percent(
891                self.as_mut_ptr(),
892                busy.as_mut_ptr(),
893                percent.as_mut_ptr(),
894            );
895
896            (from_glib(busy.assume_init()), percent.assume_init())
897        }
898    }
899
900    #[doc(alias = "get_range")]
901    #[doc(alias = "gst_query_parse_buffering_range")]
902    pub fn range(&self) -> (GenericFormattedValue, GenericFormattedValue, i64) {
903        unsafe {
904            let mut fmt = mem::MaybeUninit::uninit();
905            let mut start = mem::MaybeUninit::uninit();
906            let mut stop = mem::MaybeUninit::uninit();
907            let mut estimated_total = mem::MaybeUninit::uninit();
908
909            ffi::gst_query_parse_buffering_range(
910                self.as_mut_ptr(),
911                fmt.as_mut_ptr(),
912                start.as_mut_ptr(),
913                stop.as_mut_ptr(),
914                estimated_total.as_mut_ptr(),
915            );
916            (
917                GenericFormattedValue::new(from_glib(fmt.assume_init()), start.assume_init()),
918                GenericFormattedValue::new(from_glib(fmt.assume_init()), stop.assume_init()),
919                estimated_total.assume_init(),
920            )
921        }
922    }
923
924    #[doc(alias = "get_stats")]
925    #[doc(alias = "gst_query_parse_buffering_stats")]
926    pub fn stats(&self) -> (crate::BufferingMode, i32, i32, i64) {
927        unsafe {
928            let mut mode = mem::MaybeUninit::uninit();
929            let mut avg_in = mem::MaybeUninit::uninit();
930            let mut avg_out = mem::MaybeUninit::uninit();
931            let mut buffering_left = mem::MaybeUninit::uninit();
932
933            ffi::gst_query_parse_buffering_stats(
934                self.as_mut_ptr(),
935                mode.as_mut_ptr(),
936                avg_in.as_mut_ptr(),
937                avg_out.as_mut_ptr(),
938                buffering_left.as_mut_ptr(),
939            );
940
941            (
942                from_glib(mode.assume_init()),
943                avg_in.assume_init(),
944                avg_out.assume_init(),
945                buffering_left.assume_init(),
946            )
947        }
948    }
949
950    #[doc(alias = "get_ranges")]
951    #[doc(alias = "gst_query_get_n_buffering_ranges")]
952    #[doc(alias = "gst_query_parse_nth_buffering_range")]
953    pub fn ranges(&self) -> RangesIter<'_> {
954        RangesIter::new(self)
955    }
956
957    #[doc(alias = "gst_query_set_buffering_percent")]
958    pub fn set_percent(&mut self, busy: bool, percent: i32) {
959        unsafe {
960            ffi::gst_query_set_buffering_percent(self.as_mut_ptr(), busy.into_glib(), percent);
961        }
962    }
963
964    #[doc(alias = "gst_query_set_buffering_range")]
965    pub fn set_range<V: FormattedValue>(
966        &mut self,
967        start: V,
968        stop: impl CompatibleFormattedValue<V>,
969        estimated_total: i64,
970    ) {
971        assert_eq!(self.format(), start.format());
972        let stop = stop.try_into_checked(start).unwrap();
973
974        unsafe {
975            ffi::gst_query_set_buffering_range(
976                self.as_mut_ptr(),
977                start.format().into_glib(),
978                start.into_raw_value(),
979                stop.into_raw_value(),
980                estimated_total,
981            );
982        }
983    }
984
985    #[doc(alias = "gst_query_set_buffering_stats")]
986    pub fn set_stats(
987        &mut self,
988        mode: crate::BufferingMode,
989        avg_in: i32,
990        avg_out: i32,
991        buffering_left: i64,
992    ) {
993        skip_assert_initialized!();
994        unsafe {
995            ffi::gst_query_set_buffering_stats(
996                self.as_mut_ptr(),
997                mode.into_glib(),
998                avg_in,
999                avg_out,
1000                buffering_left,
1001            );
1002        }
1003    }
1004
1005    #[doc(alias = "gst_query_add_buffering_range")]
1006    pub fn add_buffering_ranges<V: FormattedValue, U: CompatibleFormattedValue<V> + Copy>(
1007        &mut self,
1008        ranges: impl IntoIterator<Item = (V, U)>,
1009    ) {
1010        unsafe {
1011            let fmt = self.format();
1012
1013            for (start, stop) in ranges.into_iter() {
1014                assert_eq!(start.format(), fmt);
1015                let stop = stop.try_into_checked(start).unwrap();
1016                ffi::gst_query_add_buffering_range(
1017                    self.as_mut_ptr(),
1018                    start.into_raw_value(),
1019                    stop.into_raw_value(),
1020                );
1021            }
1022        }
1023    }
1024}
1025
1026impl std::fmt::Debug for Buffering {
1027    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1028        struct RangesDebug<'a>(&'a Buffering);
1029
1030        impl std::fmt::Debug for RangesDebug<'_> {
1031            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1032                f.debug_list().entries(self.0.ranges()).finish()
1033            }
1034        }
1035
1036        f.debug_struct("Buffering")
1037            .field("structure", &self.query().structure())
1038            .field("format", &self.format())
1039            .field("percent", &self.percent())
1040            .field("range", &RangesDebug(self))
1041            .finish()
1042    }
1043}
1044
1045impl std::fmt::Debug for Buffering<Query> {
1046    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1047        Buffering::<QueryRef>::fmt(self, f)
1048    }
1049}
1050
1051crate::utils::define_fixed_size_iter!(
1052    RangesIter,
1053    &'a Buffering,
1054    (GenericFormattedValue, GenericFormattedValue),
1055    |collection: &Buffering| unsafe {
1056        ffi::gst_query_get_n_buffering_ranges(collection.as_mut_ptr()) as usize
1057    },
1058    |collection: &Buffering, idx: usize| unsafe {
1059        let mut fmt = mem::MaybeUninit::uninit();
1060        ffi::gst_query_parse_buffering_range(
1061            collection.as_mut_ptr(),
1062            fmt.as_mut_ptr(),
1063            ptr::null_mut(),
1064            ptr::null_mut(),
1065            ptr::null_mut(),
1066        );
1067        let fmt = from_glib(fmt.assume_init());
1068
1069        let mut start = mem::MaybeUninit::uninit();
1070        let mut stop = mem::MaybeUninit::uninit();
1071        ffi::gst_query_parse_nth_buffering_range(
1072            collection.as_mut_ptr(),
1073            idx as u32,
1074            start.as_mut_ptr(),
1075            stop.as_mut_ptr(),
1076        );
1077
1078        (
1079            GenericFormattedValue::new(fmt, start.assume_init()),
1080            GenericFormattedValue::new(fmt, stop.assume_init()),
1081        )
1082    }
1083);
1084
1085declare_concrete_query!(Custom, T);
1086impl Custom<Query> {
1087    #[doc(alias = "gst_query_new_custom")]
1088    pub fn new(structure: crate::Structure) -> Self {
1089        skip_assert_initialized!();
1090        unsafe {
1091            Self(from_glib_full(ffi::gst_query_new_custom(
1092                ffi::GST_QUERY_CUSTOM,
1093                structure.into_glib_ptr(),
1094            )))
1095        }
1096    }
1097}
1098
1099impl std::fmt::Debug for Custom {
1100    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1101        f.debug_struct("Custom")
1102            .field("structure", &self.query().structure())
1103            .finish()
1104    }
1105}
1106
1107impl std::fmt::Debug for Custom<Query> {
1108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1109        Custom::<QueryRef>::fmt(self, f)
1110    }
1111}
1112
1113declare_concrete_query!(Uri, T);
1114impl Uri<Query> {
1115    #[doc(alias = "gst_query_new_uri")]
1116    pub fn new() -> Self {
1117        assert_initialized_main_thread!();
1118        unsafe { Self(from_glib_full(ffi::gst_query_new_uri())) }
1119    }
1120}
1121
1122impl Default for Uri<Query> {
1123    fn default() -> Self {
1124        Self::new()
1125    }
1126}
1127
1128impl Uri {
1129    #[doc(alias = "get_uri")]
1130    #[doc(alias = "gst_query_parse_uri")]
1131    pub fn uri(&self) -> Option<glib::GString> {
1132        unsafe {
1133            let mut uri = ptr::null_mut();
1134            ffi::gst_query_parse_uri(self.as_mut_ptr(), &mut uri);
1135            from_glib_full(uri)
1136        }
1137    }
1138
1139    #[doc(alias = "get_redirection")]
1140    #[doc(alias = "gst_query_parse_uri_redirection")]
1141    #[doc(alias = "gst_query_parse_uri_redirection_permanent")]
1142    pub fn redirection(&self) -> (Option<glib::GString>, bool) {
1143        unsafe {
1144            let mut uri = ptr::null_mut();
1145            ffi::gst_query_parse_uri_redirection(self.as_mut_ptr(), &mut uri);
1146            let mut permanent = mem::MaybeUninit::uninit();
1147            ffi::gst_query_parse_uri_redirection_permanent(
1148                self.as_mut_ptr(),
1149                permanent.as_mut_ptr(),
1150            );
1151
1152            (from_glib_full(uri), from_glib(permanent.assume_init()))
1153        }
1154    }
1155
1156    #[doc(alias = "gst_query_set_uri")]
1157    pub fn set_uri<'a, T>(&mut self, uri: impl Into<Option<&'a T>>)
1158    where
1159        T: 'a + AsRef<str> + ?Sized,
1160    {
1161        unsafe {
1162            ffi::gst_query_set_uri(
1163                self.as_mut_ptr(),
1164                uri.into().map(AsRef::as_ref).to_glib_none().0,
1165            );
1166        }
1167    }
1168
1169    #[doc(alias = "gst_query_set_uri_redirection")]
1170    #[doc(alias = "gst_query_set_uri_redirection_permanent")]
1171    pub fn set_redirection<'a, T>(&mut self, uri: impl Into<Option<&'a T>>, permanent: bool)
1172    where
1173        T: 'a + AsRef<str> + ?Sized,
1174    {
1175        unsafe {
1176            ffi::gst_query_set_uri_redirection(
1177                self.as_mut_ptr(),
1178                uri.into().map(AsRef::as_ref).to_glib_none().0,
1179            );
1180            ffi::gst_query_set_uri_redirection_permanent(
1181                self.0.as_mut_ptr(),
1182                permanent.into_glib(),
1183            );
1184        }
1185    }
1186}
1187
1188impl std::fmt::Debug for Uri {
1189    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1190        let (redirection, permanent) = self.redirection();
1191        f.debug_struct("Uri")
1192            .field("structure", &self.query().structure())
1193            .field("uri", &self.uri())
1194            .field("redirection", &redirection)
1195            .field("redirection-permanent", &permanent)
1196            .finish()
1197    }
1198}
1199
1200impl std::fmt::Debug for Uri<Query> {
1201    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1202        Uri::<QueryRef>::fmt(self, f)
1203    }
1204}
1205
1206declare_concrete_query!(Allocation, T);
1207impl Allocation<Query> {
1208    #[doc(alias = "gst_query_new_allocation")]
1209    pub fn new(caps: Option<&crate::Caps>, need_pool: bool) -> Self {
1210        skip_assert_initialized!();
1211        unsafe {
1212            Self(from_glib_full(ffi::gst_query_new_allocation(
1213                caps.map(|caps| caps.as_mut_ptr())
1214                    .unwrap_or(ptr::null_mut()),
1215                need_pool.into_glib(),
1216            )))
1217        }
1218    }
1219}
1220
1221impl Allocation {
1222    #[doc(alias = "gst_query_parse_allocation")]
1223    pub fn get(&self) -> (Option<&crate::CapsRef>, bool) {
1224        unsafe {
1225            let mut caps = ptr::null_mut();
1226            let mut need_pool = mem::MaybeUninit::uninit();
1227
1228            ffi::gst_query_parse_allocation(self.as_mut_ptr(), &mut caps, need_pool.as_mut_ptr());
1229            (
1230                if caps.is_null() {
1231                    None
1232                } else {
1233                    Some(crate::CapsRef::from_ptr(caps))
1234                },
1235                from_glib(need_pool.assume_init()),
1236            )
1237        }
1238    }
1239
1240    #[doc(alias = "gst_query_parse_allocation")]
1241    pub fn get_owned(&self) -> (Option<crate::Caps>, bool) {
1242        unsafe {
1243            let (caps, need_pool) = self.get();
1244            (caps.map(|caps| from_glib_none(caps.as_ptr())), need_pool)
1245        }
1246    }
1247
1248    #[doc(alias = "gst_allocation_params")]
1249    #[doc(alias = "gst_query_get_n_allocation_params")]
1250    #[doc(alias = "gst_query_parse_nth_allocation_param")]
1251    pub fn allocation_params(&self) -> AllocationParamsIter<'_> {
1252        AllocationParamsIter::new(self)
1253    }
1254
1255    #[doc(alias = "get_allocation_pools")]
1256    #[doc(alias = "gst_query_get_n_allocation_pools")]
1257    #[doc(alias = "gst_query_parse_nth_allocation_pool")]
1258    pub fn allocation_pools(&self) -> AllocationPoolsIter<'_> {
1259        AllocationPoolsIter::new(self)
1260    }
1261
1262    #[doc(alias = "get_allocation_metas")]
1263    #[doc(alias = "gst_query_get_n_allocation_metas")]
1264    #[doc(alias = "gst_query_parse_nth_allocation_meta")]
1265    pub fn allocation_metas(&self) -> AllocationMetasIter<'_> {
1266        AllocationMetasIter::new(self)
1267    }
1268
1269    #[doc(alias = "gst_query_find_allocation_meta")]
1270    pub fn find_allocation_meta<U: crate::MetaAPI>(&self) -> Option<u32> {
1271        unsafe {
1272            let mut idx = mem::MaybeUninit::uninit();
1273            if ffi::gst_query_find_allocation_meta(
1274                self.as_mut_ptr(),
1275                U::meta_api().into_glib(),
1276                idx.as_mut_ptr(),
1277            ) != glib::ffi::GFALSE
1278            {
1279                Some(idx.assume_init())
1280            } else {
1281                None
1282            }
1283        }
1284    }
1285
1286    #[doc(alias = "gst_query_add_allocation_pool")]
1287    pub fn add_allocation_pool(
1288        &mut self,
1289        pool: Option<&impl IsA<crate::BufferPool>>,
1290        size: u32,
1291        min_buffers: u32,
1292        max_buffers: u32,
1293    ) {
1294        unsafe {
1295            ffi::gst_query_add_allocation_pool(
1296                self.as_mut_ptr(),
1297                pool.to_glib_none().0 as *mut ffi::GstBufferPool,
1298                size,
1299                min_buffers,
1300                max_buffers,
1301            );
1302        }
1303    }
1304
1305    #[doc(alias = "gst_query_set_nth_allocation_pool")]
1306    pub fn set_nth_allocation_pool(
1307        &mut self,
1308        idx: u32,
1309        pool: Option<&impl IsA<crate::BufferPool>>,
1310        size: u32,
1311        min_buffers: u32,
1312        max_buffers: u32,
1313    ) {
1314        unsafe {
1315            let n = ffi::gst_query_get_n_allocation_pools(self.as_mut_ptr());
1316            assert!(idx < n);
1317            ffi::gst_query_set_nth_allocation_pool(
1318                self.as_mut_ptr(),
1319                idx,
1320                pool.to_glib_none().0 as *mut ffi::GstBufferPool,
1321                size,
1322                min_buffers,
1323                max_buffers,
1324            );
1325        }
1326    }
1327
1328    #[doc(alias = "gst_query_remove_nth_allocation_pool")]
1329    pub fn remove_nth_allocation_pool(&mut self, idx: u32) {
1330        unsafe {
1331            let n = ffi::gst_query_get_n_allocation_pools(self.as_mut_ptr());
1332            assert!(idx < n);
1333            ffi::gst_query_remove_nth_allocation_pool(self.as_mut_ptr(), idx);
1334        }
1335    }
1336
1337    #[doc(alias = "gst_query_add_allocation_param")]
1338    pub fn add_allocation_param(
1339        &mut self,
1340        allocator: Option<&impl IsA<crate::Allocator>>,
1341        params: crate::AllocationParams,
1342    ) {
1343        unsafe {
1344            ffi::gst_query_add_allocation_param(
1345                self.as_mut_ptr(),
1346                allocator.to_glib_none().0 as *mut ffi::GstAllocator,
1347                params.as_ptr(),
1348            );
1349        }
1350    }
1351
1352    #[doc(alias = "gst_query_set_nth_allocation_param")]
1353    pub fn set_nth_allocation_param(
1354        &mut self,
1355        idx: u32,
1356        allocator: Option<&impl IsA<crate::Allocator>>,
1357        params: crate::AllocationParams,
1358    ) {
1359        unsafe {
1360            let n = ffi::gst_query_get_n_allocation_params(self.as_mut_ptr());
1361            assert!(idx < n);
1362            ffi::gst_query_set_nth_allocation_param(
1363                self.as_mut_ptr(),
1364                idx,
1365                allocator.to_glib_none().0 as *mut ffi::GstAllocator,
1366                params.as_ptr(),
1367            );
1368        }
1369    }
1370
1371    #[doc(alias = "gst_query_remove_nth_allocation_param")]
1372    pub fn remove_nth_allocation_param(&mut self, idx: u32) {
1373        unsafe {
1374            let n = ffi::gst_query_get_n_allocation_params(self.as_mut_ptr());
1375            assert!(idx < n);
1376            ffi::gst_query_remove_nth_allocation_param(self.as_mut_ptr(), idx);
1377        }
1378    }
1379
1380    #[doc(alias = "gst_query_add_allocation_meta")]
1381    pub fn add_allocation_meta<U: crate::MetaAPI>(
1382        &mut self,
1383        structure: Option<&crate::StructureRef>,
1384    ) {
1385        unsafe {
1386            ffi::gst_query_add_allocation_meta(
1387                self.as_mut_ptr(),
1388                U::meta_api().into_glib(),
1389                if let Some(structure) = structure {
1390                    structure.as_ptr()
1391                } else {
1392                    ptr::null()
1393                },
1394            );
1395        }
1396    }
1397
1398    #[doc(alias = "gst_query_remove_nth_allocation_meta")]
1399    pub fn remove_nth_allocation_meta(&mut self, idx: u32) {
1400        unsafe {
1401            let n = ffi::gst_query_get_n_allocation_metas(self.as_mut_ptr());
1402            assert!(idx < n);
1403            ffi::gst_query_remove_nth_allocation_meta(self.as_mut_ptr(), idx);
1404        }
1405    }
1406}
1407
1408impl std::fmt::Debug for Allocation {
1409    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1410        let (caps, need_pool) = self.get();
1411
1412        struct AllocationParamsDebug<'a>(&'a Allocation);
1413
1414        impl std::fmt::Debug for AllocationParamsDebug<'_> {
1415            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1416                f.debug_list().entries(self.0.allocation_params()).finish()
1417            }
1418        }
1419
1420        struct AllocationPoolsDebug<'a>(&'a Allocation);
1421
1422        impl std::fmt::Debug for AllocationPoolsDebug<'_> {
1423            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1424                f.debug_list().entries(self.0.allocation_pools()).finish()
1425            }
1426        }
1427
1428        struct AllocationMetasDebug<'a>(&'a Allocation);
1429
1430        impl std::fmt::Debug for AllocationMetasDebug<'_> {
1431            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1432                f.debug_list().entries(self.0.allocation_metas()).finish()
1433            }
1434        }
1435
1436        f.debug_struct("Allocation")
1437            .field("structure", &self.query().structure())
1438            .field("caps", &caps)
1439            .field("need-pool", &need_pool)
1440            .field("allocation-params", &AllocationParamsDebug(self))
1441            .field("allocation-pools", &AllocationPoolsDebug(self))
1442            .field("allocation-metas", &AllocationMetasDebug(self))
1443            .finish()
1444    }
1445}
1446
1447impl std::fmt::Debug for Allocation<Query> {
1448    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1449        Allocation::<QueryRef>::fmt(self, f)
1450    }
1451}
1452
1453crate::utils::define_fixed_size_iter!(
1454    AllocationParamsIter,
1455    &'a Allocation,
1456    (Option<crate::Allocator>, crate::AllocationParams),
1457    |collection: &Allocation| unsafe {
1458        ffi::gst_query_get_n_allocation_params(collection.as_mut_ptr()) as usize
1459    },
1460    |collection: &Allocation, idx: usize| unsafe {
1461        let mut allocator = ptr::null_mut();
1462        let mut p = mem::MaybeUninit::uninit();
1463        ffi::gst_query_parse_nth_allocation_param(
1464            collection.as_mut_ptr(),
1465            idx as u32,
1466            &mut allocator,
1467            p.as_mut_ptr(),
1468        );
1469        (from_glib_full(allocator), from_glib(p.assume_init()))
1470    }
1471);
1472
1473crate::utils::define_fixed_size_iter!(
1474    AllocationPoolsIter,
1475    &'a Allocation,
1476    (Option<crate::BufferPool>, u32, u32, u32),
1477    |collection: &Allocation| unsafe {
1478        ffi::gst_query_get_n_allocation_pools(collection.as_mut_ptr()) as usize
1479    },
1480    |collection: &Allocation, idx: usize| unsafe {
1481        let mut pool = ptr::null_mut();
1482        let mut size = mem::MaybeUninit::uninit();
1483        let mut min_buffers = mem::MaybeUninit::uninit();
1484        let mut max_buffers = mem::MaybeUninit::uninit();
1485
1486        ffi::gst_query_parse_nth_allocation_pool(
1487            collection.as_mut_ptr(),
1488            idx as u32,
1489            &mut pool,
1490            size.as_mut_ptr(),
1491            min_buffers.as_mut_ptr(),
1492            max_buffers.as_mut_ptr(),
1493        );
1494
1495        (
1496            from_glib_full(pool),
1497            size.assume_init(),
1498            min_buffers.assume_init(),
1499            max_buffers.assume_init(),
1500        )
1501    }
1502);
1503
1504crate::utils::define_fixed_size_iter!(
1505    AllocationMetasIter,
1506    &'a Allocation,
1507    (glib::Type, Option<&'a crate::StructureRef>),
1508    |collection: &Allocation| unsafe {
1509        ffi::gst_query_get_n_allocation_metas(collection.as_mut_ptr()) as usize
1510    },
1511    |collection: &Allocation, idx: usize| unsafe {
1512        let mut structure = ptr::null();
1513
1514        let api = ffi::gst_query_parse_nth_allocation_meta(
1515            collection.as_mut_ptr(),
1516            idx as u32,
1517            &mut structure,
1518        );
1519
1520        (
1521            from_glib(api),
1522            if structure.is_null() {
1523                None
1524            } else {
1525                Some(crate::StructureRef::from_glib_borrow(structure))
1526            },
1527        )
1528    }
1529);
1530
1531declare_concrete_query!(Scheduling, T);
1532impl Scheduling<Query> {
1533    #[doc(alias = "gst_query_new_scheduling")]
1534    pub fn new() -> Self {
1535        assert_initialized_main_thread!();
1536        unsafe { Self(from_glib_full(ffi::gst_query_new_scheduling())) }
1537    }
1538}
1539
1540impl Default for Scheduling<Query> {
1541    fn default() -> Self {
1542        Self::new()
1543    }
1544}
1545
1546impl Scheduling {
1547    #[doc(alias = "gst_query_has_scheduling_mode")]
1548    pub fn has_scheduling_mode(&self, mode: crate::PadMode) -> bool {
1549        unsafe {
1550            from_glib(ffi::gst_query_has_scheduling_mode(
1551                self.as_mut_ptr(),
1552                mode.into_glib(),
1553            ))
1554        }
1555    }
1556
1557    #[doc(alias = "gst_query_has_scheduling_mode_with_flags")]
1558    pub fn has_scheduling_mode_with_flags(
1559        &self,
1560        mode: crate::PadMode,
1561        flags: crate::SchedulingFlags,
1562    ) -> bool {
1563        skip_assert_initialized!();
1564        unsafe {
1565            from_glib(ffi::gst_query_has_scheduling_mode_with_flags(
1566                self.as_mut_ptr(),
1567                mode.into_glib(),
1568                flags.into_glib(),
1569            ))
1570        }
1571    }
1572
1573    #[doc(alias = "get_scheduling_modes")]
1574    #[doc(alias = "gst_query_get_n_scheduling_modes")]
1575    pub fn scheduling_modes(&self) -> PadModesIter<'_> {
1576        PadModesIter::new(self)
1577    }
1578
1579    #[doc(alias = "get_result")]
1580    #[doc(alias = "gst_query_parse_scheduling")]
1581    pub fn result(&self) -> (crate::SchedulingFlags, i32, i32, i32) {
1582        unsafe {
1583            let mut flags = mem::MaybeUninit::uninit();
1584            let mut minsize = mem::MaybeUninit::uninit();
1585            let mut maxsize = mem::MaybeUninit::uninit();
1586            let mut align = mem::MaybeUninit::uninit();
1587
1588            ffi::gst_query_parse_scheduling(
1589                self.as_mut_ptr(),
1590                flags.as_mut_ptr(),
1591                minsize.as_mut_ptr(),
1592                maxsize.as_mut_ptr(),
1593                align.as_mut_ptr(),
1594            );
1595
1596            (
1597                from_glib(flags.assume_init()),
1598                minsize.assume_init(),
1599                maxsize.assume_init(),
1600                align.assume_init(),
1601            )
1602        }
1603    }
1604
1605    #[doc(alias = "gst_query_add_scheduling_mode")]
1606    pub fn add_scheduling_modes(&mut self, modes: impl IntoIterator<Item = crate::PadMode>) {
1607        unsafe {
1608            for mode in modes.into_iter() {
1609                ffi::gst_query_add_scheduling_mode(self.as_mut_ptr(), mode.into_glib());
1610            }
1611        }
1612    }
1613
1614    #[doc(alias = "gst_query_set_scheduling")]
1615    pub fn set(&mut self, flags: crate::SchedulingFlags, minsize: i32, maxsize: i32, align: i32) {
1616        unsafe {
1617            ffi::gst_query_set_scheduling(
1618                self.as_mut_ptr(),
1619                flags.into_glib(),
1620                minsize,
1621                maxsize,
1622                align,
1623            );
1624        }
1625    }
1626}
1627
1628impl std::fmt::Debug for Scheduling {
1629    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1630        struct PadModesDebug<'a>(&'a Scheduling);
1631
1632        impl std::fmt::Debug for PadModesDebug<'_> {
1633            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1634                f.debug_list().entries(self.0.scheduling_modes()).finish()
1635            }
1636        }
1637
1638        f.debug_struct("Scheduling")
1639            .field("structure", &self.query().structure())
1640            .field("result", &self.result())
1641            .field("scheduling-modes", &PadModesDebug(self))
1642            .finish()
1643    }
1644}
1645
1646impl std::fmt::Debug for Scheduling<Query> {
1647    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1648        Scheduling::<QueryRef>::fmt(self, f)
1649    }
1650}
1651
1652crate::utils::define_fixed_size_iter!(
1653    PadModesIter,
1654    &'a Scheduling,
1655    crate::PadMode,
1656    |collection: &Scheduling| unsafe {
1657        ffi::gst_query_get_n_scheduling_modes(collection.as_mut_ptr()) as usize
1658    },
1659    |collection: &Scheduling, idx: usize| unsafe {
1660        from_glib(ffi::gst_query_parse_nth_scheduling_mode(
1661            collection.as_mut_ptr(),
1662            idx as u32,
1663        ))
1664    }
1665);
1666
1667declare_concrete_query!(AcceptCaps, T);
1668impl AcceptCaps<Query> {
1669    #[doc(alias = "gst_query_new_accept_caps")]
1670    pub fn new(caps: &crate::Caps) -> Self {
1671        skip_assert_initialized!();
1672        unsafe {
1673            Self(from_glib_full(ffi::gst_query_new_accept_caps(
1674                caps.as_mut_ptr(),
1675            )))
1676        }
1677    }
1678}
1679
1680impl AcceptCaps {
1681    #[doc(alias = "get_caps")]
1682    #[doc(alias = "gst_query_parse_accept_caps")]
1683    pub fn caps(&self) -> &crate::CapsRef {
1684        unsafe {
1685            let mut caps = ptr::null_mut();
1686            ffi::gst_query_parse_accept_caps(self.as_mut_ptr(), &mut caps);
1687            crate::CapsRef::from_ptr(caps)
1688        }
1689    }
1690
1691    #[doc(alias = "get_caps_owned")]
1692    #[doc(alias = "gst_query_parse_accept_caps")]
1693    pub fn caps_owned(&self) -> crate::Caps {
1694        unsafe { from_glib_none(self.caps().as_ptr()) }
1695    }
1696
1697    #[doc(alias = "get_result")]
1698    #[doc(alias = "gst_query_parse_accept_caps_result")]
1699    pub fn result(&self) -> bool {
1700        unsafe {
1701            let mut accepted = mem::MaybeUninit::uninit();
1702            ffi::gst_query_parse_accept_caps_result(self.as_mut_ptr(), accepted.as_mut_ptr());
1703            from_glib(accepted.assume_init())
1704        }
1705    }
1706
1707    #[doc(alias = "gst_query_set_accept_caps_result")]
1708    pub fn set_result(&mut self, accepted: bool) {
1709        unsafe {
1710            ffi::gst_query_set_accept_caps_result(self.as_mut_ptr(), accepted.into_glib());
1711        }
1712    }
1713}
1714
1715impl std::fmt::Debug for AcceptCaps {
1716    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1717        f.debug_struct("AcceptCaps")
1718            .field("structure", &self.query().structure())
1719            .field("result", &self.result())
1720            .field("caps", &self.caps())
1721            .finish()
1722    }
1723}
1724
1725impl std::fmt::Debug for AcceptCaps<Query> {
1726    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1727        AcceptCaps::<QueryRef>::fmt(self, f)
1728    }
1729}
1730
1731declare_concrete_query!(Caps, T);
1732impl Caps<Query> {
1733    #[doc(alias = "gst_query_new_caps")]
1734    pub fn new(filter: Option<&crate::Caps>) -> Self {
1735        skip_assert_initialized!();
1736        unsafe {
1737            Self(from_glib_full(ffi::gst_query_new_caps(
1738                filter.to_glib_none().0,
1739            )))
1740        }
1741    }
1742}
1743
1744impl Caps {
1745    #[doc(alias = "get_filter")]
1746    #[doc(alias = "gst_query_parse_caps")]
1747    pub fn filter(&self) -> Option<&crate::CapsRef> {
1748        unsafe {
1749            let mut caps = ptr::null_mut();
1750            ffi::gst_query_parse_caps(self.as_mut_ptr(), &mut caps);
1751            if caps.is_null() {
1752                None
1753            } else {
1754                Some(crate::CapsRef::from_ptr(caps))
1755            }
1756        }
1757    }
1758
1759    #[doc(alias = "get_filter_owned")]
1760    #[doc(alias = "gst_query_parse_caps")]
1761    pub fn filter_owned(&self) -> Option<crate::Caps> {
1762        unsafe { self.filter().map(|caps| from_glib_none(caps.as_ptr())) }
1763    }
1764
1765    #[doc(alias = "get_result")]
1766    #[doc(alias = "gst_query_parse_caps_result")]
1767    pub fn result(&self) -> Option<&crate::CapsRef> {
1768        unsafe {
1769            let mut caps = ptr::null_mut();
1770            ffi::gst_query_parse_caps_result(self.as_mut_ptr(), &mut caps);
1771            if caps.is_null() {
1772                None
1773            } else {
1774                Some(crate::CapsRef::from_ptr(caps))
1775            }
1776        }
1777    }
1778
1779    #[doc(alias = "get_result_owned")]
1780    #[doc(alias = "gst_query_parse_caps_result")]
1781    pub fn result_owned(&self) -> Option<crate::Caps> {
1782        unsafe { self.result().map(|caps| from_glib_none(caps.as_ptr())) }
1783    }
1784
1785    #[doc(alias = "gst_query_set_caps_result")]
1786    pub fn set_result<'a>(&mut self, caps: impl Into<Option<&'a crate::Caps>>) {
1787        unsafe {
1788            ffi::gst_query_set_caps_result(
1789                self.as_mut_ptr(),
1790                caps.into()
1791                    .map(|caps| caps.as_mut_ptr())
1792                    .unwrap_or(ptr::null_mut()),
1793            );
1794        }
1795    }
1796}
1797
1798impl std::fmt::Debug for Caps {
1799    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1800        f.debug_struct("Caps")
1801            .field("structure", &self.query().structure())
1802            .field("result", &self.result())
1803            .field("filter", &self.filter())
1804            .finish()
1805    }
1806}
1807
1808impl std::fmt::Debug for Caps<Query> {
1809    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1810        Caps::<QueryRef>::fmt(self, f)
1811    }
1812}
1813
1814declare_concrete_query!(Drain, T);
1815impl Drain<Query> {
1816    #[doc(alias = "gst_query_new_drain")]
1817    pub fn new() -> Self {
1818        assert_initialized_main_thread!();
1819        unsafe { Self(from_glib_full(ffi::gst_query_new_drain())) }
1820    }
1821}
1822
1823impl Default for Drain<Query> {
1824    fn default() -> Self {
1825        Self::new()
1826    }
1827}
1828
1829impl std::fmt::Debug for Drain {
1830    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1831        f.debug_struct("Drain")
1832            .field("structure", &self.query().structure())
1833            .finish()
1834    }
1835}
1836
1837impl std::fmt::Debug for Drain<Query> {
1838    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1839        Drain::<QueryRef>::fmt(self, f)
1840    }
1841}
1842
1843declare_concrete_query!(Context, T);
1844impl Context<Query> {
1845    #[doc(alias = "gst_query_new_context")]
1846    pub fn new(context_type: &str) -> Self {
1847        assert_initialized_main_thread!();
1848        unsafe {
1849            Self(from_glib_full(ffi::gst_query_new_context(
1850                context_type.to_glib_none().0,
1851            )))
1852        }
1853    }
1854}
1855
1856impl Context {
1857    #[doc(alias = "get_context")]
1858    #[doc(alias = "gst_query_parse_context")]
1859    pub fn context(&self) -> Option<&crate::ContextRef> {
1860        unsafe {
1861            let mut context = ptr::null_mut();
1862            ffi::gst_query_parse_context(self.as_mut_ptr(), &mut context);
1863            if context.is_null() {
1864                None
1865            } else {
1866                Some(crate::ContextRef::from_ptr(context))
1867            }
1868        }
1869    }
1870
1871    #[doc(alias = "get_context_owned")]
1872    #[doc(alias = "gst_query_parse_context")]
1873    pub fn context_owned(&self) -> Option<crate::Context> {
1874        unsafe {
1875            self.context()
1876                .map(|context| from_glib_none(context.as_ptr()))
1877        }
1878    }
1879
1880    #[doc(alias = "get_context_type")]
1881    #[doc(alias = "gst_query_parse_context_type")]
1882    pub fn context_type(&self) -> &str {
1883        unsafe {
1884            let mut context_type = ptr::null();
1885            ffi::gst_query_parse_context_type(self.as_mut_ptr(), &mut context_type);
1886            CStr::from_ptr(context_type).to_str().unwrap()
1887        }
1888    }
1889
1890    #[doc(alias = "gst_query_set_context")]
1891    pub fn set_context<'a>(&mut self, context: impl Into<Option<&'a crate::Context>>) {
1892        unsafe {
1893            ffi::gst_query_set_context(
1894                self.as_mut_ptr(),
1895                context
1896                    .into()
1897                    .map(|context| context.as_mut_ptr())
1898                    .unwrap_or(ptr::null_mut()),
1899            );
1900        }
1901    }
1902}
1903
1904impl std::fmt::Debug for Context {
1905    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1906        f.debug_struct("Context")
1907            .field("structure", &self.query().structure())
1908            .field("context", &self.context())
1909            .field("context-type", &self.context_type())
1910            .finish()
1911    }
1912}
1913
1914impl std::fmt::Debug for Context<Query> {
1915    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1916        Context::<QueryRef>::fmt(self, f)
1917    }
1918}
1919
1920#[cfg(feature = "v1_16")]
1921#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
1922declare_concrete_query!(Bitrate, T);
1923
1924#[cfg(feature = "v1_16")]
1925#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
1926impl Bitrate<Query> {
1927    #[doc(alias = "gst_query_new_bitrate")]
1928    pub fn new() -> Self {
1929        assert_initialized_main_thread!();
1930        unsafe { Self(from_glib_full(ffi::gst_query_new_bitrate())) }
1931    }
1932}
1933
1934#[cfg(feature = "v1_16")]
1935#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
1936impl Default for Bitrate<Query> {
1937    fn default() -> Self {
1938        Self::new()
1939    }
1940}
1941
1942#[cfg(feature = "v1_16")]
1943#[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
1944impl Bitrate {
1945    #[doc(alias = "get_bitrate")]
1946    #[doc(alias = "gst_query_parse_bitrate")]
1947    pub fn bitrate(&self) -> u32 {
1948        unsafe {
1949            let mut bitrate = mem::MaybeUninit::uninit();
1950            ffi::gst_query_parse_bitrate(self.as_mut_ptr(), bitrate.as_mut_ptr());
1951            bitrate.assume_init()
1952        }
1953    }
1954
1955    #[doc(alias = "gst_query_set_bitrate")]
1956    pub fn set_bitrate(&mut self, bitrate: u32) {
1957        unsafe {
1958            ffi::gst_query_set_bitrate(self.as_mut_ptr(), bitrate);
1959        }
1960    }
1961}
1962
1963#[cfg(feature = "v1_16")]
1964impl std::fmt::Debug for Bitrate {
1965    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1966        f.debug_struct("Bitrate")
1967            .field("structure", &self.query().structure())
1968            .field("bitrate", &self.bitrate())
1969            .finish()
1970    }
1971}
1972
1973#[cfg(feature = "v1_16")]
1974impl std::fmt::Debug for Bitrate<Query> {
1975    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1976        Bitrate::<QueryRef>::fmt(self, f)
1977    }
1978}
1979
1980#[cfg(feature = "v1_22")]
1981#[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
1982declare_concrete_query!(Selectable, T);
1983
1984#[cfg(feature = "v1_22")]
1985#[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
1986impl Selectable<Query> {
1987    #[doc(alias = "gst_query_new_selectable")]
1988    pub fn new() -> Self {
1989        assert_initialized_main_thread!();
1990        unsafe { Self(from_glib_full(ffi::gst_query_new_selectable())) }
1991    }
1992}
1993
1994#[cfg(feature = "v1_22")]
1995#[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
1996impl Default for Selectable<Query> {
1997    fn default() -> Self {
1998        Self::new()
1999    }
2000}
2001
2002#[cfg(feature = "v1_22")]
2003#[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
2004impl Selectable {
2005    #[doc(alias = "get_selectable")]
2006    #[doc(alias = "gst_query_parse_selectable")]
2007    pub fn selectable(&self) -> bool {
2008        unsafe {
2009            let mut selectable = mem::MaybeUninit::uninit();
2010            ffi::gst_query_parse_selectable(self.as_mut_ptr(), selectable.as_mut_ptr());
2011            from_glib(selectable.assume_init())
2012        }
2013    }
2014
2015    #[doc(alias = "gst_query_set_selectable")]
2016    pub fn set_selectable(&mut self, selectable: bool) {
2017        unsafe {
2018            ffi::gst_query_set_selectable(self.as_mut_ptr(), selectable.into_glib());
2019        }
2020    }
2021}
2022
2023#[cfg(feature = "v1_22")]
2024impl std::fmt::Debug for Selectable {
2025    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2026        f.debug_struct("Selectable")
2027            .field("structure", &self.query().structure())
2028            .field("selectable", &self.selectable())
2029            .finish()
2030    }
2031}
2032
2033#[cfg(feature = "v1_22")]
2034impl std::fmt::Debug for Selectable<Query> {
2035    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2036        Selectable::<QueryRef>::fmt(self, f)
2037    }
2038}
2039
2040declare_concrete_query!(Other, T);
2041
2042impl std::fmt::Debug for Other {
2043    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2044        f.debug_struct("Other")
2045            .field("structure", &self.query().structure())
2046            .finish()
2047    }
2048}
2049
2050impl std::fmt::Debug for Other<Query> {
2051    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2052        Other::<QueryRef>::fmt(self, f)
2053    }
2054}
2055
2056#[cfg(test)]
2057mod tests {
2058    use super::*;
2059    use crate::ClockTime;
2060
2061    #[test]
2062    fn test_writability() {
2063        crate::init().unwrap();
2064
2065        fn check_mut(query: &mut QueryRef) {
2066            skip_assert_initialized!();
2067            match query.view_mut() {
2068                QueryViewMut::Position(p) => {
2069                    let pos = p.result();
2070                    assert_eq!(pos.try_into(), Ok(ClockTime::NONE));
2071                    p.set(Some(3 * ClockTime::SECOND));
2072                    let pos = p.result();
2073                    assert_eq!(pos.try_into(), Ok(Some(3 * ClockTime::SECOND)));
2074                }
2075                _ => panic!("Wrong concrete Query in Query"),
2076            }
2077        }
2078
2079        fn check_ref(query: &QueryRef) {
2080            skip_assert_initialized!();
2081            match query.view() {
2082                QueryView::Position(p) => {
2083                    let pos = p.result();
2084                    assert_eq!(pos.try_into(), Ok(Some(3 * ClockTime::SECOND)));
2085                    assert!(!p.as_mut_ptr().is_null());
2086                }
2087                _ => panic!("Wrong concrete Query in Query"),
2088            }
2089        }
2090
2091        let mut p = Position::new(crate::Format::Time);
2092        let pos = p.result();
2093        assert_eq!(pos.try_into(), Ok(ClockTime::NONE));
2094
2095        p.structure_mut().set("check_mut", true);
2096
2097        // deref
2098        assert!(!p.is_serialized());
2099
2100        {
2101            check_mut(&mut p);
2102
2103            let structure = p.structure();
2104            structure.unwrap().has_field("check_mut");
2105
2106            // Expected: cannot borrow `p` as mutable because it is also borrowed as immutable
2107            //check_mut(&mut p);
2108        }
2109
2110        check_ref(&p);
2111    }
2112
2113    #[test]
2114    fn test_into_query() {
2115        crate::init().unwrap();
2116        let d = Duration::new(crate::Format::Time);
2117
2118        let mut query: Query = d.into();
2119        assert!(query.is_writable());
2120
2121        let query = query.make_mut();
2122        if let QueryViewMut::Duration(d) = query.view_mut() {
2123            d.set(Some(2 * ClockTime::SECOND));
2124        }
2125
2126        if let QueryView::Duration(d) = query.view() {
2127            let duration = d.result();
2128            assert_eq!(duration.try_into(), Ok(Some(2 * ClockTime::SECOND)));
2129        }
2130    }
2131
2132    #[test]
2133    fn test_concrete_to_sys() {
2134        crate::init().unwrap();
2135
2136        let p = Position::new(crate::Format::Time);
2137        assert!(!p.as_mut_ptr().is_null());
2138    }
2139
2140    #[test]
2141    fn allocation_need_pool() {
2142        crate::init().unwrap();
2143
2144        let mut a = Allocation::new(Some(&crate::Caps::new_empty_simple("foo/bar")), true);
2145        let pool = crate::BufferPool::new();
2146        a.add_allocation_pool(Some(&pool), 1024, 1, 4);
2147    }
2148
2149    #[test]
2150    fn allocation_do_not_need_pool() {
2151        crate::init().unwrap();
2152
2153        let mut a = Allocation::new(Some(&crate::Caps::new_empty_simple("foo/bar")), false);
2154        a.add_allocation_pool(crate::BufferPool::NONE, 1024, 1, 4);
2155
2156        // cannot infer type of the type parameter `T` declared on the enum `Option`
2157        //a.add_allocation_pool(None, 1024, 1, 4);
2158
2159        // This would be possible if we moved the `crate::BufferPool`
2160        // as a generic argument instead of using current arg type:
2161        // - `pool: Option<&impl IsA<crate::BufferPool>>`
2162        //a.add_allocation_pool::<crate::BufferPool>(None, 1024, 1, 4);
2163    }
2164
2165    #[test]
2166    fn set_uri() {
2167        crate::init().unwrap();
2168
2169        let mut uri_q = Uri::new();
2170        uri_q.set_uri("https://test.org");
2171        uri_q.set_uri(&String::from("https://test.org"));
2172
2173        uri_q.set_uri(Some("https://test.org"));
2174        uri_q.set_uri(Some(&String::from("https://test.org")));
2175
2176        // FIXME: this is commented out for now due to an inconsistent
2177        //        assertion in `GStreamer` which results in critical logs.
2178        /*
2179        let none: Option<&str> = None;
2180        uri_q.set_uri(none);
2181
2182        let none: Option<String> = None;
2183        uri_q.set_uri(none.as_ref());
2184
2185        uri_q.set_uri::<str>(None);
2186        */
2187    }
2188}