cubeb_core/
device_collection.rs

1// Copyright © 2017-2018 Mozilla Foundation
2//
3// This program is made available under an ISC-style license.  See the
4// accompanying file LICENSE for details.
5
6use ffi;
7use ffi_types;
8use std::{ops, slice};
9use {ContextRef, DeviceInfo};
10
11/// A collection of `DeviceInfo` used by libcubeb
12type CType = ffi::cubeb_device_collection;
13
14#[derive(Debug)]
15pub struct DeviceCollection<'ctx>(CType, &'ctx ContextRef);
16
17impl DeviceCollection<'_> {
18    pub(crate) fn init_with_ctx(ctx: &ContextRef, coll: CType) -> DeviceCollection<'_> {
19        DeviceCollection(coll, ctx)
20    }
21
22    pub fn as_ptr(&self) -> *mut CType {
23        &self.0 as *const CType as *mut CType
24    }
25}
26
27impl Drop for DeviceCollection<'_> {
28    fn drop(&mut self) {
29        unsafe {
30            let _ = call!(ffi::cubeb_device_collection_destroy(
31                self.1.as_ptr(),
32                &mut self.0
33            ));
34        }
35    }
36}
37
38impl ::std::ops::Deref for DeviceCollection<'_> {
39    type Target = DeviceCollectionRef;
40
41    #[inline]
42    fn deref(&self) -> &DeviceCollectionRef {
43        let ptr = &self.0 as *const CType as *mut CType;
44        unsafe { DeviceCollectionRef::from_ptr(ptr) }
45    }
46}
47
48impl ::std::convert::AsRef<DeviceCollectionRef> for DeviceCollection<'_> {
49    #[inline]
50    fn as_ref(&self) -> &DeviceCollectionRef {
51        self
52    }
53}
54
55pub struct DeviceCollectionRef(ffi_types::Opaque);
56
57impl DeviceCollectionRef {
58    /// # Safety
59    ///
60    /// This function is unsafe because it dereferences the given `ptr` pointer.
61    /// The caller should ensure that pointer is valid.
62    #[inline]
63    pub unsafe fn from_ptr<'a>(ptr: *mut CType) -> &'a Self {
64        &*(ptr as *mut _)
65    }
66
67    /// # Safety
68    ///
69    /// This function is unsafe because it dereferences the given `ptr` pointer.
70    /// The caller should ensure that pointer is valid.
71    #[inline]
72    pub unsafe fn from_ptr_mut<'a>(ptr: *mut CType) -> &'a mut Self {
73        &mut *(ptr as *mut _)
74    }
75
76    #[inline]
77    pub fn as_ptr(&self) -> *mut CType {
78        self as *const _ as *mut _
79    }
80}
81
82impl ::std::fmt::Debug for DeviceCollectionRef {
83    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
84        let ptr = self as *const DeviceCollectionRef as usize;
85        f.debug_tuple(stringify!(DeviceCollectionRef))
86            .field(&ptr)
87            .finish()
88    }
89}
90
91impl ops::Deref for DeviceCollectionRef {
92    type Target = [DeviceInfo];
93    fn deref(&self) -> &[DeviceInfo] {
94        unsafe {
95            let coll: &ffi::cubeb_device_collection = &*self.as_ptr();
96            slice::from_raw_parts(coll.device as *const DeviceInfo, coll.count)
97        }
98    }
99}