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