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> {
14 ptr: ptr::NonNull<pw_sys::pw_stream>,
15 core: PhantomData<&'c Core>,
16}
17
18impl<'c> StreamBox<'c> {
19 pub fn new(
23 core: &'c Core,
24 name: &str,
25 properties: PropertiesBox,
26 ) -> Result<StreamBox<'c>, Error> {
27 let name = CString::new(name).expect("Invalid byte in stream name");
28
29 let c_str = name.as_c_str();
30 StreamBox::new_cstr(core, c_str, properties)
31 }
32
33 pub fn new_cstr(
35 core: &'c Core,
36 name: &CStr,
37 properties: PropertiesBox,
38 ) -> Result<StreamBox<'c>, Error> {
39 unsafe {
40 let stream =
41 pw_sys::pw_stream_new(core.as_raw_ptr(), name.as_ptr(), properties.into_raw());
42 let stream = ptr::NonNull::new(stream).ok_or(Error::CreationFailed)?;
43
44 Ok(Self::from_raw(stream))
45 }
46 }
47
48 pub unsafe fn from_raw(raw: ptr::NonNull<pw_sys::pw_stream>) -> StreamBox<'c> {
59 Self {
60 ptr: raw,
61 core: PhantomData,
62 }
63 }
64
65 pub fn into_raw(self) -> ptr::NonNull<pw_sys::pw_stream> {
66 std::mem::ManuallyDrop::new(self).ptr
67 }
68}
69
70impl<'c> std::ops::Deref for StreamBox<'c> {
71 type Target = Stream;
72
73 fn deref(&self) -> &Self::Target {
74 unsafe { self.ptr.cast().as_ref() }
75 }
76}
77
78impl<'c> std::fmt::Debug for StreamBox<'c> {
79 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80 f.debug_struct("StreamBox")
81 .field("name", &self.name())
82 .field("state", &self.state())
83 .field("node-id", &self.node_id())
84 .field("properties", &self.properties())
85 .finish()
86 }
87}
88
89impl<'c> std::ops::Drop for StreamBox<'c> {
90 fn drop(&mut self) {
91 unsafe { pw_sys::pw_stream_destroy(self.as_raw_ptr()) }
92 }
93}