1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
 * SPDX-License-Identifier: MIT
 */

//! Wrappers for the external types
//!
use std::mem::ManuallyDrop;
use std::ops::{Deref, DerefMut};

use crate::spa::interface::InterfaceRef;

/// Owned wrapper for the external type.
/// Should be used when external value can be created or dropped from the Rust side,
/// or when Wrapper should have additional fields.
/// Methods wrappers can be implemented in the [RawWrapper] and used from the both variants.
/// Usually Wrappers have only constructor and drop implementations.
pub trait Wrapper
where
    Self: Deref<Target = Self::RawWrapperType>,
    Self: DerefMut<Target = Self::RawWrapperType>,
    Self: AsRef<Self::RawWrapperType>,
    Self: AsMut<Self::RawWrapperType>,
    Self: Sized,
{
    /// [RawWrapper] type
    type RawWrapperType: RawWrapper;

    /// Converts the Wrapper into raw pointer, that must be dropped manually.
    /// Used when the external method takes the ownership.
    #[must_use]
    fn into_raw(self) -> *mut <Self::RawWrapperType as RawWrapper>::CType {
        ManuallyDrop::new(self).as_raw()
    }

    /// Raw mutable pointer to the external value.
    fn as_raw(&self) -> *mut <Self::RawWrapperType as RawWrapper>::CType {
        self.as_ref().as_raw_ptr()
    }
}

/// Wrapper for the external type, must not be null.
/// By convention, all wrapped structures should with the Ref prefix.
/// #\[repr(transparent)\] should be used where possible.
pub trait RawWrapper
where
    Self: Sized,
{
    /// External type
    type CType;

    /// Raw ptr to the external type
    fn as_raw_ptr(&self) -> *mut Self::CType;

    /// Wrapped external value
    fn as_raw(&self) -> &Self::CType;

    /// Creates wrapper from the external value, can be use when external type has no raw pointers.
    fn from_raw(raw: Self::CType) -> Self;

    /// Cast external pointer to the borrowed wrapper.
    /// Panic when pointer is null.
    /// Lifetime is not reliable and should be guaranteed explicitly.
    ///
    /// # Arguments
    ///
    /// * `raw` - raw pointer
    ///
    /// # Safety
    ///
    /// `raw` must be valid pointer to the structure
    unsafe fn from_raw_ptr<'a>(raw: *const Self::CType) -> &'a Self {
        Self::mut_from_raw_ptr(raw as *mut Self::CType)
    }

    /// Cast external pointer to the borrowed mutable wrapper.
    /// Panic when pointer is null.
    /// Lifetime is not reliable and should be guaranteed explicitly.
    ///
    /// # Arguments
    ///
    /// * `raw` - raw pointer
    /// # Safety
    ///
    /// `raw` must be valid pointer to the structure
    unsafe fn mut_from_raw_ptr<'a>(raw: *mut Self::CType) -> &'a mut Self;

    /// Raw mutable pointer to Self
    fn as_ptr(&self) -> *mut Self {
        self.as_raw_ptr() as *mut Self
    }
}

/// Provides support for [spa_sys::spa_interface] methods.
/// [spa_interface_call](crate::spa_interface_call) can used to call the methods
pub trait SpaInterface: RawWrapper {
    /// [spa_sys::spa_interface] methods structure
    type Methods;

    /// Interface wrapper
    fn spa_interface(&self) -> &InterfaceRef;

    /// Interface version
    fn version(&self) -> u32 {
        self.spa_interface().version()
    }
}