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)]
28pub struct StreamRc {
29 inner: Rc<StreamRcInner>,
30}
31
32impl StreamRc {
33 pub fn new(core: CoreRc, name: &str, properties: PropertiesBox) -> Result<StreamRc, Error> {
34 let name = CString::new(name).expect("Invalid byte in stream name");
35
36 let c_str = name.as_c_str();
37 StreamRc::new_cstr(core, c_str, properties)
38 }
39
40 pub fn new_cstr(
42 core: CoreRc,
43 name: &CStr,
44 properties: PropertiesBox,
45 ) -> Result<StreamRc, Error> {
46 unsafe {
47 let stream =
48 pw_sys::pw_stream_new(core.as_raw_ptr(), name.as_ptr(), properties.into_raw());
49 let stream = ptr::NonNull::new(stream).ok_or(Error::CreationFailed)?;
50
51 let stream: StreamBox<'static> = StreamBox::from_raw(stream);
52
53 Ok(Self {
54 inner: Rc::new(StreamRcInner {
55 stream,
56 _core: core,
57 }),
58 })
59 }
60 }
61
62 pub fn downgrade(&self) -> StreamWeak {
63 let weak = Rc::downgrade(&self.inner);
64 StreamWeak { weak }
65 }
66}
67
68impl std::ops::Deref for StreamRc {
69 type Target = Stream;
70
71 fn deref(&self) -> &Self::Target {
72 self.inner.stream.deref()
73 }
74}
75
76impl std::convert::AsRef<Stream> for StreamRc {
77 fn as_ref(&self) -> &Stream {
78 self.deref()
79 }
80}
81
82pub struct StreamWeak {
83 weak: Weak<StreamRcInner>,
84}
85
86impl StreamWeak {
87 pub fn upgrade(&self) -> Option<StreamRc> {
88 self.weak.upgrade().map(|inner| StreamRc { inner })
89 }
90}