unsafe_libopus/
varargs.rs1pub enum VarArg<'a> {
4 I32(i32),
5 I32Out(&'a mut i32),
6 U32Out(&'a mut u32),
7 F32Ptr(*mut f32),
8 U8Ptr(*mut u8),
9 CustomModeOut(&'a mut *const crate::OpusCustomMode),
10 OpusDecoderOut(&'a mut *mut crate::OpusDecoder),
11 OpusEncoderOut(&'a mut *mut crate::OpusEncoder),
12 AnalysisInfoOut(&'a mut crate::src::analysis::AnalysisInfo),
13 SilkInfoOut(&'a mut crate::celt::celt_encoder::SILKInfo),
14}
15
16pub trait FromVarArg<'a> {
17 fn from_vararg(arg: VarArg<'a>) -> Self;
18}
19
20pub trait IntoVarArg<'a> {
21 fn into_vararg(self) -> VarArg<'a>;
22}
23
24macro_rules! impl_from_vararg {
25 ($t:ty, $v:ident) => {
26 impl<'a> FromVarArg<'a> for $t {
27 fn from_vararg(arg: VarArg<'a>) -> Self {
28 match arg {
29 VarArg::$v(v) => v,
30 _ => panic!("invalid vararg type"),
31 }
32 }
33 }
34 };
35}
36macro_rules! impl_into_vararg {
37 ($t:ty, $v:ident) => {
38 impl<'a> IntoVarArg<'a> for $t {
39 fn into_vararg(self) -> VarArg<'a> {
40 VarArg::$v(self)
41 }
42 }
43 };
44}
45macro_rules! impl_vararg {
46 ($t:ty, $v:ident) => {
47 impl_from_vararg!($t, $v);
48 impl_into_vararg!($t, $v);
49 };
50}
51
52impl_vararg!(i32, I32);
53impl_vararg!(&'a mut i32, I32Out);
54impl_vararg!(&'a mut u32, U32Out);
55impl_vararg!(*mut f32, F32Ptr);
56impl_vararg!(*mut u8, U8Ptr);
57impl_vararg!(&'a mut *const crate::OpusCustomMode, CustomModeOut);
58impl_vararg!(&'a mut *mut crate::OpusDecoder, OpusDecoderOut);
59impl_vararg!(&'a mut *mut crate::OpusEncoder, OpusEncoderOut);
60impl_vararg!(&'a mut crate::src::analysis::AnalysisInfo, AnalysisInfoOut);
61impl_vararg!(&'a mut crate::celt::celt_encoder::SILKInfo, SilkInfoOut);
62
63pub struct VarArgs<'a>(pub Vec<VarArg<'a>>);
64
65impl<'a> VarArgs<'a> {
66 pub fn new(mut varargs: Vec<VarArg<'a>>) -> Self {
67 varargs.reverse();
69 Self(varargs)
70 }
71
72 pub fn arg<T: FromVarArg<'a>>(&mut self) -> T {
73 T::from_vararg(
74 self.0
75 .pop()
76 .expect("Attempt to pop from empty varargs (are the function arguments correct?)"),
77 )
78 }
79}
80
81#[macro_export]
82macro_rules! varargs {
83 ($($arg:expr),*) => {
84 $crate::varargs::VarArgs::new(
85 vec![
86 $(
87 $crate::varargs::IntoVarArg::into_vararg($arg)
88 ),*
89 ]
90 )
91 };
92}