1 // Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com> 2 // 3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your 6 // option. This file may not be copied, modified, or distributed 7 // except according to those terms. 8 9 use glib::object::IsA; 10 use glib::translate::*; 11 use gst_sys; 12 use std::fmt; 13 use Stream; 14 use StreamCollection; 15 16 #[derive(Debug)] 17 pub struct Iter<'a> { 18 collection: &'a StreamCollection, 19 idx: u32, 20 size: u32, 21 } 22 23 impl<'a> Iter<'a> { new(collection: &'a StreamCollection) -> Iter<'a>24 fn new(collection: &'a StreamCollection) -> Iter<'a> { 25 skip_assert_initialized!(); 26 Iter { 27 collection, 28 idx: 0, 29 size: collection.len() as u32, 30 } 31 } 32 } 33 34 impl<'a> Iterator for Iter<'a> { 35 type Item = Stream; 36 next(&mut self) -> Option<Self::Item>37 fn next(&mut self) -> Option<Self::Item> { 38 if self.idx >= self.size { 39 return None; 40 } 41 42 let item = self.collection.get_stream(self.idx); 43 self.idx += 1; 44 45 item 46 } 47 size_hint(&self) -> (usize, Option<usize>)48 fn size_hint(&self) -> (usize, Option<usize>) { 49 if self.idx == self.size { 50 return (0, Some(0)); 51 } 52 53 let remaining = (self.size - self.idx) as usize; 54 55 (remaining, Some(remaining)) 56 } 57 } 58 59 impl<'a> DoubleEndedIterator for Iter<'a> { next_back(&mut self) -> Option<Self::Item>60 fn next_back(&mut self) -> Option<Self::Item> { 61 if self.idx == self.size { 62 return None; 63 } 64 65 self.size -= 1; 66 self.collection.get_stream(self.size) 67 } 68 } 69 70 impl<'a> ExactSizeIterator for Iter<'a> {} 71 72 impl StreamCollection { new(upstream_id: Option<&str>) -> StreamCollection73 pub fn new(upstream_id: Option<&str>) -> StreamCollection { 74 assert_initialized_main_thread!(); 75 let upstream_id = upstream_id.to_glib_none(); 76 let (major, minor, _, _) = ::version(); 77 if (major, minor) > (1, 12) { 78 unsafe { from_glib_full(gst_sys::gst_stream_collection_new(upstream_id.0)) } 79 } else { 80 // Work-around for 1.14 switching from transfer-floating to transfer-full 81 unsafe { from_glib_none(gst_sys::gst_stream_collection_new(upstream_id.0)) } 82 } 83 } 84 85 #[cfg(any(feature = "v1_10", feature = "dox"))] add_stream<P: IsA<Stream>>(&self, stream: &P)86 pub fn add_stream<P: IsA<Stream>>(&self, stream: &P) { 87 unsafe { 88 gst_sys::gst_stream_collection_add_stream( 89 self.to_glib_none().0, 90 stream.as_ref().to_glib_full(), 91 ); 92 } 93 } 94 iter(&self) -> Iter95 pub fn iter(&self) -> Iter { 96 Iter::new(self) 97 } 98 len(&self) -> usize99 pub fn len(&self) -> usize { 100 self.get_size() as usize 101 } 102 is_empty(&self) -> bool103 pub fn is_empty(&self) -> bool { 104 self.len() == 0 105 } 106 debug(&self) -> Debug107 pub fn debug(&self) -> Debug { 108 Debug(self) 109 } 110 } 111 112 pub struct Debug<'a>(&'a StreamCollection); 113 114 impl<'a> fmt::Debug for Debug<'a> { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result115 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 116 struct Streams<'a>(&'a StreamCollection); 117 118 impl<'a> fmt::Debug for Streams<'a> { 119 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 120 let mut f = f.debug_list(); 121 122 for stream in self.0.iter() { 123 f.entry(&stream.debug()); 124 } 125 126 f.finish() 127 } 128 } 129 130 let streams = Streams(self.0); 131 132 f.debug_struct("StreamCollection") 133 .field("streams", &streams) 134 .finish() 135 } 136 } 137