1use crate::{core::Core, error::Error, properties::PropertiesBox};
5use std::{
6 ffi::{CStr, CString},
7 marker::PhantomData,
8 ptr,
9};
10
11use super::Stream;
12
13pub struct StreamBox<'c> {
19 ptr: ptr::NonNull<pw_sys::pw_stream>,
20 core: PhantomData<&'c Core>,
21}
22
23impl<'c> StreamBox<'c> {
24 pub fn new(
28 core: &'c Core,
29 name: &str,
30 properties: PropertiesBox,
31 ) -> Result<StreamBox<'c>, Error> {
32 let name = CString::new(name).expect("Invalid byte in stream name");
33
34 let c_str = name.as_c_str();
35 StreamBox::new_cstr(core, c_str, properties)
36 }
37
38 pub fn new_cstr(
40 core: &'c Core,
41 name: &CStr,
42 properties: PropertiesBox,
43 ) -> Result<StreamBox<'c>, Error> {
44 unsafe {
45 let stream =
46 pw_sys::pw_stream_new(core.as_raw_ptr(), name.as_ptr(), properties.into_raw());
47 let stream = ptr::NonNull::new(stream).ok_or(Error::CreationFailed)?;
48
49 Ok(Self::from_raw(stream))
50 }
51 }
52
53 pub unsafe fn from_raw(raw: ptr::NonNull<pw_sys::pw_stream>) -> StreamBox<'c> {
64 Self {
65 ptr: raw,
66 core: PhantomData,
67 }
68 }
69
70 pub fn into_raw(self) -> ptr::NonNull<pw_sys::pw_stream> {
71 std::mem::ManuallyDrop::new(self).ptr
72 }
73}
74
75impl<'c> std::ops::Deref for StreamBox<'c> {
76 type Target = Stream;
77
78 fn deref(&self) -> &Self::Target {
79 unsafe { self.ptr.cast().as_ref() }
80 }
81}
82
83impl<'c> std::fmt::Debug for StreamBox<'c> {
84 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 f.debug_struct("StreamBox")
86 .field("name", &self.name())
87 .field("state", &self.state())
88 .field("node-id", &self.node_id())
89 .field("properties", &self.properties())
90 .finish()
91 }
92}
93
94impl<'c> std::ops::Drop for StreamBox<'c> {
95 fn drop(&mut self) {
96 unsafe { pw_sys::pw_stream_destroy(self.as_raw_ptr()) }
97 }
98}