use std::{fmt, mem::ManuallyDrop, ops::Deref, ptr};
use super::Properties;
pub struct PropertiesBox {
ptr: ptr::NonNull<pw_sys::pw_properties>,
}
impl PropertiesBox {
pub fn new() -> Self {
unsafe {
let raw = std::ptr::NonNull::new(pw_sys::pw_properties_new(std::ptr::null()))
.expect("Newly created pw_properties should not be null");
Self::from_raw(raw)
}
}
pub unsafe fn from_raw(ptr: ptr::NonNull<pw_sys::pw_properties>) -> Self {
Self { ptr }
}
pub fn into_raw(self) -> *mut pw_sys::pw_properties {
let this = ManuallyDrop::new(self);
this.ptr.as_ptr()
}
pub fn from_dict(dict: &spa::utils::dict::DictRef) -> Self {
let ptr = dict.as_raw();
unsafe {
let copy = pw_sys::pw_properties_new_dict(ptr);
Self::from_raw(ptr::NonNull::new(copy).expect("pw_properties_new_dict() returned NULL"))
}
}
}
impl AsRef<Properties> for PropertiesBox {
fn as_ref(&self) -> &Properties {
self.deref()
}
}
impl AsRef<spa::utils::dict::DictRef> for PropertiesBox {
fn as_ref(&self) -> &spa::utils::dict::DictRef {
self.deref().as_ref()
}
}
impl std::ops::Deref for PropertiesBox {
type Target = Properties;
fn deref(&self) -> &Self::Target {
unsafe { self.ptr.cast().as_ref() }
}
}
impl std::ops::DerefMut for PropertiesBox {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { self.ptr.cast().as_mut() }
}
}
impl Default for PropertiesBox {
fn default() -> Self {
Self::new()
}
}
impl Clone for PropertiesBox {
fn clone(&self) -> Self {
unsafe {
let ptr = pw_sys::pw_properties_copy(self.as_raw_ptr());
let ptr = ptr::NonNull::new_unchecked(ptr);
Self { ptr }
}
}
}
impl<K, V> FromIterator<(K, V)> for PropertiesBox
where
K: Into<Vec<u8>>,
V: Into<Vec<u8>>,
{
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
let mut props = Self::new();
props.extend(iter);
props
}
}
impl Drop for PropertiesBox {
fn drop(&mut self) {
unsafe { pw_sys::pw_properties_free(self.ptr.as_ptr()) }
}
}
impl fmt::Debug for PropertiesBox {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let dict: &spa::utils::dict::DictRef = self.as_ref();
f.debug_tuple("PropertiesBox").field(dict).finish()
}
}
#[macro_export]
macro_rules! __properties__ {
{$($k:expr => $v:expr),+ $(,)?} => {{
let mut properties = $crate::properties::PropertiesBox::new();
$(
properties.insert($k, $v);
)*
properties
}};
}
pub use __properties__ as properties;