pipewire/loop_/
box_.rs

1// Copyright The pipewire-rs Contributors.
2// SPDX-License-Identifier: MIT
3
4use std::{ops::Deref, ptr};
5
6use super::Loop;
7use crate::Error;
8
9#[derive(Debug)]
10pub struct LoopBox {
11    ptr: std::ptr::NonNull<pw_sys::pw_loop>,
12}
13
14impl LoopBox {
15    /// Create a new [`LoopBox`].
16    pub fn new(properties: Option<&spa::utils::dict::DictRef>) -> Result<Self, Error> {
17        // This is a potential "entry point" to the library, so we need to ensure it is initialized.
18        crate::init();
19
20        unsafe {
21            let props = properties
22                .map_or(ptr::null(), |props| props.as_raw())
23                .cast_mut();
24            let raw = pw_sys::pw_loop_new(props);
25            let ptr = ptr::NonNull::new(raw).ok_or(Error::CreationFailed)?;
26            Ok(Self::from_raw(ptr))
27        }
28    }
29
30    /// Create a new [`LoopBox`] from a raw [`pw_loop`](`pw_sys::pw_loop`), taking ownership of it.
31    ///
32    /// # Safety
33    /// The provided pointer must point to a valid, well aligned [`pw_loop`](`pw_sys::pw_loop`).
34    ///
35    /// The raw loop should not be manually destroyed or moved, as the new [`LoopBox`] takes ownership of it.
36    pub unsafe fn from_raw(ptr: ptr::NonNull<pw_sys::pw_loop>) -> Self {
37        Self { ptr }
38    }
39
40    pub fn into_raw(self) -> std::ptr::NonNull<pw_sys::pw_loop> {
41        std::mem::ManuallyDrop::new(self).ptr
42    }
43}
44
45impl std::ops::Deref for LoopBox {
46    type Target = Loop;
47
48    fn deref(&self) -> &Self::Target {
49        unsafe { self.ptr.cast::<Loop>().as_ref() }
50    }
51}
52
53impl AsRef<Loop> for LoopBox {
54    fn as_ref(&self) -> &Loop {
55        self.deref()
56    }
57}
58
59// The owning type implements the Drop trait to clean up the raw type automatically.
60impl std::ops::Drop for LoopBox {
61    fn drop(&mut self) {
62        unsafe {
63            pw_sys::pw_loop_destroy(self.as_raw_ptr());
64        }
65    }
66}