1use glib::translate::*;
4use gst::prelude::*;
5use std::marker::PhantomData;
6
7use crate::{RelTypes, ffi};
8
9#[repr(transparent)]
10#[doc(alias = "GstAnalyticsRelationMeta")]
11pub struct AnalyticsRelationMeta(ffi::GstAnalyticsRelationMeta);
12
13unsafe impl Send for AnalyticsRelationMeta {}
14unsafe impl Sync for AnalyticsRelationMeta {}
15
16#[derive(Debug, Copy, Clone)]
17#[doc(alias = "GstAnalyticsRelationMetaInitParams")]
18pub struct AnalyticsRelationMetaInitParams(ffi::GstAnalyticsRelationMetaInitParams);
19
20impl Default for AnalyticsRelationMetaInitParams {
21 fn default() -> Self {
22 Self(ffi::GstAnalyticsRelationMetaInitParams {
23 initial_relation_order: 0,
24 initial_buf_size: 0,
25 })
26 }
27}
28
29impl AnalyticsRelationMetaInitParams {
30 pub fn new(initial_relation_order: usize, initial_buf_size: usize) -> Self {
31 skip_assert_initialized!();
32 Self(ffi::GstAnalyticsRelationMetaInitParams {
33 initial_relation_order,
34 initial_buf_size,
35 })
36 }
37}
38
39#[derive(Debug, Clone)]
40pub struct AnalyticsMtdRef<'a, T: AnalyticsMtd> {
41 id: u32,
42 meta: gst::MetaRef<'a, AnalyticsRelationMeta>,
43 mtd_type: PhantomData<&'a T>,
44}
45
46#[derive(Debug)]
47pub struct AnalyticsMtdRefMut<'a, T: AnalyticsMtd> {
48 id: u32,
49 meta: &'a mut gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>,
50 mtd_type: PhantomData<&'a T>,
51}
52
53pub struct AnalyticsRelationPath {
54 garray: *mut glib::ffi::GArray,
55}
56
57impl std::fmt::Debug for AnalyticsRelationMeta {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
59 f.debug_struct("AnalyticsRelationMeta")
60 .field("len", &self.len())
61 .finish()
62 }
63}
64
65impl AnalyticsRelationMeta {
66 #[doc(alias = "gst_buffer_add_analytics_relation_meta")]
67 pub fn add(buffer: &mut gst::BufferRef) -> gst::MetaRefMut<'_, Self, gst::meta::Standalone> {
68 skip_assert_initialized!();
69
70 unsafe {
71 let meta_ptr = ffi::gst_buffer_add_analytics_relation_meta(buffer.as_mut_ptr());
72 Self::from_mut_ptr(buffer, meta_ptr)
73 }
74 }
75
76 #[doc(alias = "gst_buffer_add_analytics_relation_meta_full")]
77 pub fn add_full<'a>(
78 buffer: &'a mut gst::BufferRef,
79 init_params: &AnalyticsRelationMetaInitParams,
80 ) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> {
81 skip_assert_initialized!();
82
83 unsafe {
84 let meta_ptr = ffi::gst_buffer_add_analytics_relation_meta_full(
85 buffer.as_mut_ptr(),
86 mut_override(&init_params.0),
87 );
88 Self::from_mut_ptr(buffer, meta_ptr)
89 }
90 }
91
92 #[doc(alias = "gst_analytics_relation_get_length")]
93 pub fn len(&self) -> usize {
94 unsafe { ffi::gst_analytics_relation_get_length(self.as_mut_ptr()) }
95 }
96
97 pub fn is_empty(&self) -> bool {
98 self.len() == 0
99 }
100
101 #[doc(alias = "gst_analytics_relation_meta_set_relation")]
102 pub fn set_relation(
103 &mut self,
104 type_: crate::RelTypes,
105 an_meta_first_id: u32,
106 an_meta_second_id: u32,
107 ) -> Result<(), glib::BoolError> {
108 let ret = unsafe {
109 from_glib(ffi::gst_analytics_relation_meta_set_relation(
110 self.as_mut_ptr(),
111 type_.into_glib(),
112 an_meta_first_id,
113 an_meta_second_id,
114 ))
115 };
116
117 if ret {
118 Ok(())
119 } else {
120 Err(glib::bool_error!(
121 "Could not set relation {:}->{:} of type {:?}",
122 an_meta_first_id,
123 an_meta_second_id,
124 type_
125 ))
126 }
127 }
128
129 #[doc(alias = "gst_analytics_relation_meta_get_relation")]
130 pub fn relation(&self, an_meta_first_id: u32, an_meta_second_id: u32) -> crate::RelTypes {
131 unsafe {
132 from_glib(ffi::gst_analytics_relation_meta_get_relation(
133 self.as_mut_ptr(),
134 an_meta_first_id,
135 an_meta_second_id,
136 ))
137 }
138 }
139
140 #[doc(alias = "gst_analytics_relation_meta_exist")]
141 pub fn exist(
142 &self,
143 an_meta_first_id: u32,
144 an_meta_second_id: u32,
145 relation_span: i32,
146 cond_types: crate::RelTypes,
147 ) -> bool {
148 unsafe {
149 from_glib(ffi::gst_analytics_relation_meta_exist(
150 self.as_mut_ptr(),
151 an_meta_first_id,
152 an_meta_second_id,
153 relation_span,
154 cond_types.into_glib(),
155 std::ptr::null_mut(),
156 ))
157 }
158 }
159
160 #[doc(alias = "gst_analytics_relation_meta_exist")]
161 pub fn exist_path(
162 &self,
163 an_meta_first_id: u32,
164 an_meta_second_id: u32,
165 relation_span: i32,
166 cond_types: crate::RelTypes,
167 ) -> Result<AnalyticsRelationPath, glib::BoolError> {
168 let mut array = std::ptr::null_mut::<glib::ffi::GArray>();
169 let ret = unsafe {
170 from_glib(ffi::gst_analytics_relation_meta_exist(
171 self.as_mut_ptr(),
172 an_meta_first_id,
173 an_meta_second_id,
174 relation_span,
175 cond_types.into_glib(),
176 &mut array,
177 ))
178 };
179
180 if ret {
181 Ok(AnalyticsRelationPath { garray: array })
182 } else {
183 Err(glib::bool_error!("Such relation doesn't exist"))
184 }
185 }
186
187 pub unsafe fn as_mut_ptr(&self) -> *mut ffi::GstAnalyticsRelationMeta {
188 mut_override(&self.0)
189 }
190}
191
192impl UnsafeFrom<&AnalyticsRelationMeta> for ffi::GstAnalyticsMtd {
193 unsafe fn unsafe_from(t: &AnalyticsRelationMeta) -> Self {
194 unsafe {
195 ffi::GstAnalyticsMtd {
196 id: 0,
197 meta: t.as_mut_ptr(),
198 }
199 }
200 }
201}
202
203impl AnalyticsRelationPath {
204 pub fn as_slice(&self) -> &[u32] {
205 unsafe {
206 std::slice::from_raw_parts(
207 (*self.garray).data as *const u32,
208 (*self.garray).len as usize,
209 )
210 }
211 }
212}
213
214impl Drop for AnalyticsRelationPath {
215 fn drop(&mut self) {
216 unsafe {
217 glib::ffi::g_array_free(self.garray, glib::ffi::GTRUE);
218 }
219 }
220}
221
222mod sealed {
223 pub trait Sealed {}
224 impl<T> Sealed for T {}
225}
226
227pub trait AnalyticsMetaRefExt<'a>: sealed::Sealed {
228 #[doc(alias = "gst_analytics_relation_meta_get_mtd")]
229 fn mtd<T: AnalyticsMtd>(&self, an_meta_id: u32) -> Option<AnalyticsMtdRef<'a, T>>;
230 fn iter<T: AnalyticsMtd>(&'a self) -> AnalyticsMtdIter<'a, T>;
231 fn iter_direct_related<T: AnalyticsMtd>(
232 &'a self,
233 an_meta_id: u32,
234 rel_type: RelTypes,
235 ) -> AnalyticsMtdIter<'a, T>;
236}
237
238impl<'a> AnalyticsMetaRefExt<'a> for gst::MetaRef<'a, AnalyticsRelationMeta> {
239 fn mtd<T: AnalyticsMtd>(&self, an_meta_id: u32) -> Option<AnalyticsMtdRef<'a, T>> {
240 unsafe {
241 let mut mtd = std::mem::MaybeUninit::uninit();
242 let ret = from_glib(ffi::gst_analytics_relation_meta_get_mtd(
243 self.as_mut_ptr(),
244 an_meta_id,
245 T::mtd_type(),
246 mtd.as_mut_ptr(),
247 ));
248 let id = mtd.assume_init().id;
249
250 if ret {
251 Some(AnalyticsMtdRef::from_meta(self, id))
252 } else {
253 None
254 }
255 }
256 }
257
258 fn iter<T: AnalyticsMtd>(&'a self) -> AnalyticsMtdIter<'a, T> {
259 AnalyticsMtdIter::new(self)
260 }
261 fn iter_direct_related<T: AnalyticsMtd>(
262 &'a self,
263 an_meta_id: u32,
264 rel_type: RelTypes,
265 ) -> AnalyticsMtdIter<'a, T> {
266 AnalyticsMtdIter::new_direct_related(self, an_meta_id, rel_type.into_glib())
267 }
268}
269
270impl<'a, T: AnalyticsMtd> AnalyticsMtdRef<'a, T> {
271 pub fn id(&self) -> u32 {
272 self.id
273 }
274
275 pub unsafe fn from_meta(meta: &gst::MetaRef<'a, AnalyticsRelationMeta>, id: u32) -> Self {
276 skip_assert_initialized!();
277 AnalyticsMtdRef {
278 meta: meta.clone(),
279 id,
280 mtd_type: PhantomData,
281 }
282 }
283
284 #[doc(alias = "gst_analytics_mtd_get_mtd_type")]
285 pub fn mtd_type(&self) -> ffi::GstAnalyticsMtdType {
286 unsafe {
287 let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
288 ffi::gst_analytics_mtd_get_mtd_type(&mtd)
289 }
290 }
291}
292impl<'a> AnalyticsMtdRef<'a, AnalyticsAnyMtd> {
293 pub fn downcast<T: AnalyticsMtd>(
294 self,
295 ) -> Result<AnalyticsMtdRef<'a, T>, AnalyticsMtdRef<'a, AnalyticsAnyMtd>> {
296 if self.mtd_type() == T::mtd_type() {
297 Ok(AnalyticsMtdRef {
298 id: self.id,
299 meta: self.meta,
300 mtd_type: PhantomData,
301 })
302 } else {
303 Err(self)
304 }
305 }
306
307 pub fn downcast_ref<T: AnalyticsMtd>(&self) -> Option<&AnalyticsMtdRef<'a, T>> {
308 unsafe {
309 if self.mtd_type() == T::mtd_type() {
310 Some(&*(self as *const _ as *const _))
311 } else {
312 None
313 }
314 }
315 }
316}
317
318impl<'a> AnalyticsMtdRefMut<'a, AnalyticsAnyMtd> {
319 pub fn downcast_mut<T: AnalyticsMtd>(&mut self) -> Option<&mut AnalyticsMtdRefMut<'a, T>> {
320 unsafe {
321 if self.as_ref().mtd_type() == T::mtd_type() {
322 Some(&mut *(self as *mut _ as *mut _))
323 } else {
324 None
325 }
326 }
327 }
328}
329
330impl<'a, T: AnalyticsMtd> UnsafeFrom<&AnalyticsMtdRef<'a, T>> for ffi::GstAnalyticsMtd {
331 unsafe fn unsafe_from(t: &AnalyticsMtdRef<'a, T>) -> Self {
332 unsafe {
333 ffi::GstAnalyticsMtd {
334 id: t.id,
335 meta: t.meta.as_mut_ptr(),
336 }
337 }
338 }
339}
340
341pub trait AnalyticsMetaRefMutExt<'a>: sealed::Sealed {
342 #[doc(alias = "gst_analytics_relation_meta_get_mtd")]
343 fn mtd_mut<T: AnalyticsMtd>(&'a mut self, an_meta_id: u32)
344 -> Option<AnalyticsMtdRefMut<'a, T>>;
345
346 fn iter_mut<T: AnalyticsMtd>(&'a mut self) -> AnalyticsMtdIterMut<'a, T>;
347 fn iter_direct_related_mut<T: AnalyticsMtd>(
348 &'a mut self,
349 an_meta_id: u32,
350 rel_type: RelTypes,
351 ) -> AnalyticsMtdIterMut<'a, T>;
352}
353
354impl<'a> AnalyticsMetaRefMutExt<'a>
355 for gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>
356{
357 fn mtd_mut<T: AnalyticsMtd>(
358 &'a mut self,
359 an_meta_id: u32,
360 ) -> Option<AnalyticsMtdRefMut<'a, T>> {
361 unsafe {
362 let mut mtd = std::mem::MaybeUninit::uninit();
363 let ret = from_glib(ffi::gst_analytics_relation_meta_get_mtd(
364 self.as_mut_ptr(),
365 an_meta_id,
366 T::mtd_type(),
367 mtd.as_mut_ptr(),
368 ));
369 let id = mtd.assume_init().id;
370
371 if ret {
372 Some(AnalyticsMtdRefMut::from_meta(self, id))
373 } else {
374 None
375 }
376 }
377 }
378
379 fn iter_mut<T: AnalyticsMtd>(&'a mut self) -> AnalyticsMtdIterMut<'a, T> {
380 AnalyticsMtdIterMut::new(self)
381 }
382 fn iter_direct_related_mut<T: AnalyticsMtd>(
383 &'a mut self,
384 an_meta_id: u32,
385 rel_type: RelTypes,
386 ) -> AnalyticsMtdIterMut<'a, T> {
387 AnalyticsMtdIterMut::new_direct_related(self, an_meta_id, rel_type.into_glib())
388 }
389}
390
391unsafe impl MetaAPI for AnalyticsRelationMeta {
392 type GstType = ffi::GstAnalyticsRelationMeta;
393
394 #[doc(alias = "gst_analytics_relation_meta_api_get_type")]
395 #[inline]
396 fn meta_api() -> glib::Type {
397 unsafe { from_glib(ffi::gst_analytics_relation_meta_api_get_type()) }
398 }
399}
400
401pub unsafe trait AnalyticsMtd {
402 fn mtd_type() -> ffi::GstAnalyticsMtdType;
403}
404
405pub trait AnalyticsMtdExt: AnalyticsMtd {
406 #[doc(alias = "gst_analytics_mtd_type_get_name")]
407 fn type_name() -> &'static str {
408 unsafe {
409 let ptr = ffi::gst_analytics_mtd_type_get_name(Self::mtd_type());
410 std::ffi::CStr::from_ptr(ptr).to_str().unwrap()
411 }
412 }
413}
414
415impl<T: AnalyticsMtd> AnalyticsMtdExt for T {}
416
417impl<'a, T: AnalyticsMtd> AnalyticsMtdRefMut<'a, T> {
418 pub fn id(&self) -> u32 {
419 self.id
420 }
421
422 pub unsafe fn from_meta(
423 meta: &'a mut gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>,
424 id: u32,
425 ) -> Self {
426 skip_assert_initialized!();
427 AnalyticsMtdRefMut {
428 meta,
429 id,
430 mtd_type: PhantomData,
431 }
432 }
433}
434
435impl<'a, T: AnalyticsMtd> UnsafeFrom<&mut AnalyticsMtdRefMut<'a, T>> for ffi::GstAnalyticsMtd {
436 unsafe fn unsafe_from(t: &mut AnalyticsMtdRefMut<'a, T>) -> Self {
437 ffi::GstAnalyticsMtd {
438 id: t.id,
439 meta: t.meta.as_mut_ptr(),
440 }
441 }
442}
443
444impl<'a, T: AnalyticsMtd> From<AnalyticsMtdRefMut<'a, T>> for AnalyticsMtdRef<'a, T> {
445 fn from(value: AnalyticsMtdRefMut<'a, T>) -> Self {
446 skip_assert_initialized!();
447 AnalyticsMtdRef {
448 meta: value.meta.as_ref().clone(),
449 id: value.id,
450 mtd_type: value.mtd_type,
451 }
452 }
453}
454
455impl<'a, T: AnalyticsMtd> From<&mut AnalyticsMtdRefMut<'a, T>> for AnalyticsMtdRef<'a, T> {
456 fn from(value: &mut AnalyticsMtdRefMut<'a, T>) -> Self {
457 skip_assert_initialized!();
458 AnalyticsMtdRef {
459 meta: value.meta.as_ref().clone(),
460 id: value.id,
461 mtd_type: value.mtd_type,
462 }
463 }
464}
465
466impl<'a, T: AnalyticsMtd> AsRef<AnalyticsMtdRef<'a, T>> for AnalyticsMtdRefMut<'a, T> {
467 #[inline]
468 fn as_ref(&self) -> &AnalyticsMtdRef<'a, T> {
469 unsafe { &*(self as *const AnalyticsMtdRefMut<'a, T> as *const AnalyticsMtdRef<'a, T>) }
470 }
471}
472
473macro_rules! define_mtd_iter {
474 ($name:ident, $metaref:ty, $itemref:ty, $copy_meta:expr) => {
475 #[must_use = "iterators are lazy and do nothing unless consumed"]
476 pub struct $name<'a, T: AnalyticsMtd> {
477 meta: $metaref,
478 state: glib::ffi::gpointer,
479 mtd_type: ffi::GstAnalyticsMtdType,
480 an_meta_id: u32,
481 rel_type: ffi::GstAnalyticsRelTypes,
482 phantom: std::marker::PhantomData<T>,
483 }
484
485 impl<'a, T: AnalyticsMtd> $name<'a, T> {
486 fn new(meta: $metaref) -> Self {
487 skip_assert_initialized!();
488 $name {
489 meta,
490 state: std::ptr::null_mut(),
491 mtd_type: T::mtd_type(),
492 an_meta_id: u32::MAX,
493 rel_type: RelTypes::ANY.into_glib(),
494 phantom: PhantomData,
495 }
496 }
497 fn new_direct_related(
498 meta: $metaref,
499 an_meta_id: u32,
500 rel_type: ffi::GstAnalyticsRelTypes,
501 ) -> Self {
502 skip_assert_initialized!();
503 $name {
504 meta,
505 state: std::ptr::null_mut(),
506 mtd_type: T::mtd_type(),
507 an_meta_id,
508 rel_type,
509 phantom: PhantomData,
510 }
511 }
512 }
513
514 impl<'a, T: AnalyticsMtd + 'a> Iterator for $name<'a, T> {
515 type Item = $itemref;
516
517 fn next(&mut self) -> Option<Self::Item> {
518 unsafe {
519 let mut mtd = ffi::GstAnalyticsMtd::unsafe_from(&**self.meta);
520 let ret = {
521 if self.an_meta_id == u32::MAX {
522 ffi::gst_analytics_relation_meta_iterate(
523 self.meta.as_mut_ptr(),
524 &mut self.state,
525 self.mtd_type,
526 &mut mtd,
527 )
528 } else {
529 ffi::gst_analytics_relation_meta_get_direct_related(
530 self.meta.as_mut_ptr(),
531 self.an_meta_id,
532 self.rel_type,
533 self.mtd_type,
534 &mut self.state,
535 &mut mtd,
536 )
537 }
538 };
539 if from_glib(ret) {
540 #[allow(clippy::redundant_closure_call)]
543 Some(Self::Item::from_meta($copy_meta(self.meta), mtd.id))
544 } else {
545 None
546 }
547 }
548 }
549 }
550 };
551}
552
553define_mtd_iter!(
554 AnalyticsMtdIter,
555 &'a gst::MetaRef<'a, AnalyticsRelationMeta>,
556 AnalyticsMtdRef<'a, T>,
557 |meta| meta
558);
559
560define_mtd_iter!(
561 AnalyticsMtdIterMut,
562 &'a mut gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>,
563 AnalyticsMtdRefMut<'a, T>,
564 |meta: &mut _| &mut *(meta as *mut gst::MetaRefMut<
565 'a,
566 AnalyticsRelationMeta,
567 gst::meta::Standalone,
568 >)
569);
570
571#[derive(Debug)]
572pub enum AnalyticsAnyMtd {}
573
574unsafe impl AnalyticsMtd for AnalyticsAnyMtd {
575 fn mtd_type() -> ffi::GstAnalyticsMtdType {
576 ffi::GST_ANALYTICS_MTD_TYPE_ANY as ffi::GstAnalyticsMtdType
577 }
578}
579
580#[cfg(test)]
581mod tests {
582 use crate::*;
583
584 #[test]
585 fn build_relation_meta() {
586 gst::init().unwrap();
587
588 let mut buf = gst::Buffer::new();
589
590 let meta = AnalyticsRelationMeta::add(buf.make_mut());
591
592 assert!(meta.is_empty());
593 }
594
595 #[test]
596 fn build_relation_meta_full() {
597 gst::init().unwrap();
598
599 let mut buf = gst::Buffer::new();
600
601 let params = AnalyticsRelationMetaInitParams::new(10, 10);
602 let meta = AnalyticsRelationMeta::add_full(buf.make_mut(), ¶ms);
603
604 assert!(meta.is_empty());
605 }
606
607 #[test]
608 fn relations() {
609 gst::init().unwrap();
610
611 let mut buf = gst::Buffer::new();
612 let _ = AnalyticsRelationMeta::add(buf.make_mut());
613
614 let mut meta = buf.make_mut().meta_mut::<AnalyticsRelationMeta>().unwrap();
615 let od = meta
616 .add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
617 .unwrap();
618 let od1_id = od.id();
619
620 let od = meta
621 .add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
622 .unwrap();
623 let od2_id = od.id();
624
625 let od: AnalyticsMtdRef<'_, AnalyticsODMtd> = meta
626 .add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
627 .unwrap();
628 let od3_id = od.id();
629
630 meta.set_relation(RelTypes::IS_PART_OF, od1_id, od2_id)
631 .unwrap();
632 meta.set_relation(RelTypes::IS_PART_OF, od2_id, od3_id)
633 .unwrap();
634
635 meta.set_relation(RelTypes::IS_PART_OF, 8888, 9999)
636 .expect_err("Invalid id");
637
638 let meta = buf.meta::<AnalyticsRelationMeta>().unwrap();
639 assert!(meta.relation(od1_id, od2_id) == crate::RelTypes::IS_PART_OF);
640 assert!(meta.relation(od2_id, od3_id) == crate::RelTypes::IS_PART_OF);
641
642 assert!(meta.exist(od1_id, od2_id, 1, crate::RelTypes::IS_PART_OF));
643 assert!(meta.exist(od1_id, od3_id, 2, crate::RelTypes::IS_PART_OF));
644 assert!(!meta.exist(od2_id, od1_id, 1, crate::RelTypes::IS_PART_OF));
645 assert!(!meta.exist(od1_id, od3_id, 1, crate::RelTypes::IS_PART_OF));
646 assert!(!meta.exist(od1_id, od2_id, 1, crate::RelTypes::CONTAIN));
647
648 let path = meta
649 .exist_path(od1_id, od3_id, 3, crate::RelTypes::ANY)
650 .unwrap();
651
652 assert_eq!(path.as_slice().len(), 3);
653 assert_eq!(path.as_slice()[0], od1_id);
654 assert_eq!(path.as_slice()[1], od2_id);
655 assert_eq!(path.as_slice()[2], od3_id);
656
657 assert_eq!(meta.len(), meta.iter::<AnalyticsAnyMtd>().count());
658 assert_eq!(meta.len(), meta.iter::<AnalyticsODMtd>().count());
659 for mtd in meta.iter::<AnalyticsODMtd>() {
660 assert_eq!(mtd.obj_type().unwrap(), glib::Quark::from_str("blb"))
661 }
662
663 assert_eq!(meta.len(), meta.iter::<AnalyticsAnyMtd>().count());
664 for mtd in meta.iter::<AnalyticsAnyMtd>() {
665 if let Ok(mtd) = mtd.downcast::<AnalyticsODMtd>() {
666 assert_eq!(mtd.obj_type().unwrap(), glib::Quark::from_str("blb"))
667 }
668 }
669
670 assert_eq!(
671 meta.iter_direct_related::<AnalyticsODMtd>(od1_id, crate::RelTypes::IS_PART_OF)
672 .count(),
673 1
674 );
675 assert_eq!(
676 meta.iter_direct_related::<AnalyticsODMtd>(od2_id, crate::RelTypes::IS_PART_OF)
677 .count(),
678 1
679 );
680 assert_eq!(
681 meta.iter_direct_related::<AnalyticsODMtd>(od3_id, crate::RelTypes::IS_PART_OF)
682 .count(),
683 0
684 );
685 assert_eq!(
686 meta.iter_direct_related::<AnalyticsODMtd>(od1_id, crate::RelTypes::CONTAIN)
687 .count(),
688 0
689 );
690
691 assert_eq!(
692 meta.iter_direct_related::<AnalyticsAnyMtd>(od1_id, crate::RelTypes::CONTAIN)
693 .count(),
694 0
695 );
696 for mtd in meta.iter_direct_related::<AnalyticsODMtd>(od1_id, crate::RelTypes::IS_PART_OF) {
697 assert_eq!(mtd.obj_type().unwrap(), glib::Quark::from_str("blb"))
698 }
699
700 let mut meta = buf.make_mut().meta_mut::<AnalyticsRelationMeta>().unwrap();
701 assert_eq!(meta.len(), meta.iter_mut::<AnalyticsAnyMtd>().count());
702
703 let mut meta = buf.make_mut().meta_mut::<AnalyticsRelationMeta>().unwrap();
704 let _ = meta.add_tracking_mtd(10, gst::ClockTime::from_seconds(10));
705 let _ = meta.add_tracking_mtd(10, gst::ClockTime::from_seconds(10));
706
707 for mut item in meta.iter_mut::<AnalyticsTrackingMtd>() {
708 item.set_lost().unwrap();
709 }
710 }
711}