1use std::{
5 ffi::{CStr, CString},
6 ops::Deref,
7 ptr,
8 rc::{Rc, Weak},
9};
10
11use crate::{
12 core::CoreRc,
13 properties::PropertiesBox,
14 stream::{Stream, StreamBox},
15 Error,
16};
17
18#[derive(Debug)]
19struct StreamRcInner {
20 stream: StreamBox<'static>,
21 _core: CoreRc,
25}
26
27#[derive(Clone, Debug)]
34pub struct StreamRc {
35 inner: Rc<StreamRcInner>,
36}
37
38impl StreamRc {
39 pub fn new(core: CoreRc, name: &str, properties: PropertiesBox) -> Result<StreamRc, Error> {
40 let name = CString::new(name).expect("Invalid byte in stream name");
41
42 let c_str = name.as_c_str();
43 StreamRc::new_cstr(core, c_str, properties)
44 }
45
46 pub fn new_cstr(
48 core: CoreRc,
49 name: &CStr,
50 properties: PropertiesBox,
51 ) -> Result<StreamRc, Error> {
52 unsafe {
53 let stream =
54 pw_sys::pw_stream_new(core.as_raw_ptr(), name.as_ptr(), properties.into_raw());
55 let stream = ptr::NonNull::new(stream).ok_or(Error::CreationFailed)?;
56
57 let stream: StreamBox<'static> = StreamBox::from_raw(stream);
58
59 Ok(Self {
60 inner: Rc::new(StreamRcInner {
61 stream,
62 _core: core,
63 }),
64 })
65 }
66 }
67
68 pub fn downgrade(&self) -> StreamWeak {
69 let weak = Rc::downgrade(&self.inner);
70 StreamWeak { weak }
71 }
72}
73
74impl std::ops::Deref for StreamRc {
75 type Target = Stream;
76
77 fn deref(&self) -> &Self::Target {
78 self.inner.stream.deref()
79 }
80}
81
82impl std::convert::AsRef<Stream> for StreamRc {
83 fn as_ref(&self) -> &Stream {
84 self.deref()
85 }
86}
87
88pub struct StreamWeak {
92 weak: Weak<StreamRcInner>,
93}
94
95impl StreamWeak {
96 pub fn upgrade(&self) -> Option<StreamRc> {
97 self.weak.upgrade().map(|inner| StreamRc { inner })
98 }
99}