Skip to main content

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