nvapi_sys/
macros.rs

1macro_rules! nv_declare_handle {
2    (
3        $(#[$meta:meta])*
4        $name:ident
5    ) => {
6        $(#[$meta])*
7        #[derive(Copy, Clone, Debug)]
8        pub struct $name(*const ::std::os::raw::c_void);
9
10        impl Default for $name {
11            fn default() -> Self {
12                $name(::std::ptr::null())
13            }
14        }
15    };
16}
17
18macro_rules! nvinherit {
19    (
20        $v2:ident($id:ident: $v1:ty)
21    ) => {
22        impl ::std::ops::Deref for $v2 {
23            type Target = $v1;
24
25            fn deref(&self) -> &Self::Target {
26                &self.$id
27            }
28        }
29
30        impl ::std::ops::DerefMut for $v2 {
31            fn deref_mut(&mut self) -> &mut Self::Target {
32                &mut self.$id
33            }
34        }
35    };
36}
37
38macro_rules! nvstruct {
39    (
40        $(#[$meta:meta])*
41        pub struct $name:ident {
42            $($tt:tt)*
43        }
44    ) => {
45        $(#[$meta])*
46        #[repr(C)]
47        #[derive(Copy, Clone, Debug)]
48        pub struct $name {
49            $($tt)*
50        }
51
52        impl $name {
53            pub fn zeroed() -> Self {
54                unsafe { ::std::mem::zeroed() }
55            }
56        }
57    };
58}
59
60macro_rules! nvenum {
61    (
62        $(#[$meta:meta])*
63        pub enum $enum:ident / $enum_name:ident {
64            $(
65                $(#[$metai:meta])*
66                $symbol:ident / $name:ident = $value:expr,
67            )*
68        }
69    ) => {
70        $(#[$meta])*
71        pub type $enum = ::std::os::raw::c_int;
72        $(
73            $(#[$metai])*
74            pub const $symbol: $enum = $value as _;
75        )*
76
77        $(#[$meta])*
78        #[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))]
79        #[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
80        #[repr(i32)]
81        pub enum $enum_name {
82            $(
83                $(#[$metai])*
84                $name = $symbol as _,
85            )*
86        }
87
88        impl $enum_name {
89            pub fn from_raw(raw: $enum) -> ::std::result::Result<Self, ::ArgumentRangeError> {
90                match raw {
91                    $(
92                        $symbol
93                    )|* => Ok(unsafe { ::std::mem::transmute(raw) }),
94                    _ => Err(Default::default()),
95                }
96            }
97
98            pub fn raw(&self) -> $enum {
99                *self as _
100            }
101
102            pub fn values() -> ::std::iter::Cloned<::std::slice::Iter<'static, Self>> {
103                [
104                    $(
105                        $enum_name::$name
106                    ),*
107                ].into_iter().cloned()
108            }
109        }
110
111        impl Into<$enum> for $enum_name {
112            fn into(self) -> $enum {
113                self as _
114            }
115        }
116    };
117}
118
119macro_rules! nvbits {
120    (
121        $(#[$meta:meta])*
122        pub enum $enum:ident / $enum_name:ident {
123            $(
124                $(#[$($metai:tt)*])*
125                $symbol:ident / $name:ident = $value:expr,
126            )*
127        }
128    ) => {
129        $(#[$meta])*
130        pub type $enum = u32;
131        $(
132            $(#[$($metai)*])*
133            pub const $symbol: $enum = $value as _;
134        )*
135
136        bitflags! {
137            $(#[$meta])*
138            #[derive(Default)]
139            #[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))]
140            pub struct $enum_name: $enum {
141            $(
142                $(#[$($metai)*])*
143                const $name = $value;
144            )*
145            }
146        }
147
148        impl Iterator for $enum_name {
149            type Item = Self;
150
151            fn next(&mut self) -> Option<Self::Item> {
152                $(
153                    if self.contains($enum_name::$name) {
154                        self.remove($enum_name::$name);
155                        Some($enum_name::$name)
156                    } else
157                 )*
158                { None }
159            }
160        }
161    };
162}
163
164macro_rules! nvenum_display {
165    ($enum:ident => _) => {
166        impl ::std::fmt::Display for $enum {
167            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
168                ::std::fmt::Debug::fmt(self, f)
169            }
170        }
171    };
172    ($enum:ident => {
173        $(
174            $name:tt = $value:tt,
175        )*
176    }) => {
177        impl ::std::fmt::Display for $enum {
178            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
179                match *self {
180                $(
181                    nvenum_display!(@q $enum $name) => nvenum_display!(@expr self f $value),
182                    //$enum::$name => nvenum_display!(@expr self f $value),
183                )*
184                }
185            }
186        }
187    };
188    (@q $enum:ident _) => {
189        _
190    };
191    (@q $enum:ident $name:ident) => {
192        $enum::$name
193    };
194    (@expr $this:tt $fmt:ident _) => {
195        ::std::fmt::Debug::fmt($this, $fmt)
196    };
197    (@expr $this:tt $fmt:ident $expr:expr) => {
198        write!($fmt, "{}", $expr)
199    };
200}
201
202macro_rules! nvapi {
203    (
204        $(#[$meta:meta])*
205        pub unsafe fn $fn:ident($($arg:ident: $arg_ty:ty),*) -> $ret:ty;
206    ) => {
207        $(#[$meta])*
208        pub unsafe fn $fn($($arg: $arg_ty),*) -> $ret {
209            static CACHE: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::AtomicUsize::new(0);
210
211            match ::nvapi::query_interface(::nvid::Api::$fn.id(), &CACHE) {
212                Ok(ptr) => ::std::mem::transmute::<_, extern "C" fn($($arg: $arg_ty),*) -> $ret>(ptr)($($arg),*),
213                Err(e) => e.raw(),
214            }
215        }
216    };
217    (
218        pub type $name:ident = extern "C" fn($($arg:ident: $arg_ty:ty),*) -> $ret:ty;
219
220        $(#[$meta:meta])*
221        pub unsafe fn $fn:ident;
222    ) => {
223        pub type $name = extern "C" fn($($arg: $arg_ty),*) -> $ret;
224
225        nvapi! {
226            $(#[$meta])*
227            pub unsafe fn $fn($($arg: $arg_ty),*) -> $ret;
228        }
229    };
230}
231
232// No `const fn` yet :(
233macro_rules! nvversion {
234    ($name:ident($struct:ident = $sz:expr, $ver:expr)) => {
235        pub const $name: u32 = ($sz) as u32 | ($ver as u32) << 16;
236        /*pub fn $name() -> u32 {
237            MAKE_NVAPI_VERSION::<$struct>($ver)
238        }*/
239
240        mod $name {
241            #[test]
242            fn $name() {
243                assert_eq!(::types::GET_NVAPI_SIZE(super::$name), ::std::mem::size_of::<super::$struct>());
244            }
245        }
246    };
247    ($name:ident = $target:ident) => {
248        pub const $name: u32 = $target;
249        /*pub fn $name() -> u32 {
250            $target()
251        }*/
252    };
253}
254