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