Bug 1946184 - Fix computing the CSD margin right after calling HideWindowChrome(...
[gecko.git] / toolkit / components / bitsdownload / src / bits_interface / xpcom_methods.rs
blobcb267b9634dd8313d8eb51c1064888e41878f6d4
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /// This macro is very similar to xpcom_macro, but works a bit differently:
6 ///
7 /// When possible, it returns errors via the callback rather than via the return
8 /// value.
9 ///
10 /// It implicitly adds the callback argument of type: nsIBitsNewRequestCallback
11 ///
12 /// It needs an action type, to be specified before the rust name, in square
13 /// brackets.
14 ///
15 /// The rustic implementation that the xpcom method calls is expected to return
16 /// the type: Result<_, BitsTaskError>. If this value is Ok, it will be ignored.
17 /// If the value is Err, it will be returned via the callback passed.
18 ///
19 /// Usage like this:
20 ///
21 /// ```ignore
22 ///     nsIBits_method!(
23 ///         [ActionType]
24 ///         rust_method => XpcomMethod(
25 ///             foo: *const nsACString,
26 ///             bar: *const nsIBar,
27 ///             baz: bool,
28 ///             [optional] qux: *const nsIQux,
29 ///         )
30 ///     );
31 /// ```
32 ///
33 /// Results in the macro generating a method like:
34 ///
35 /// ```ignore
36 ///     unsafe fn XpcomMethod(
37 ///         &self,
38 ///         foo: *const nsACString,
39 ///         bar: *const nsIBar,
40 ///         baz: bool,
41 ///         qux: *const nsIQux,
42 ///         callback: *const nsIBitsNewRequestCallback,
43 ///     ) -> nsresult {
44 ///         let callback: &nsIBitsNewRequestCallback = match xpcom::Ensure::ensure(callback) {
45 ///             Ok(val) => val,
46 ///             Err(result) => return result,
47 ///         };
48 ///         let foo = match xpcom::Ensure::ensure(foo) {
49 ///             Ok(val) => val,
50 ///             Err(_) => {
51 ///                 dispatch_pretask_interface_error(BitsTaskError::new(ErrorType::NullArgument, ActionType.into(), ErrorStage::Pretask), callback);
52 ///                 return NS_OK;
53 ///             }
54 ///         };
55 ///         let bar = match xpcom::Ensure::ensure(bar) {
56 ///             Ok(val) => val,
57 ///             Err(_) => {
58 ///                 dispatch_pretask_interface_error(BitsTaskError::new(ErrorType::NullArgument, ActionType.into(), ErrorStage::Pretask), callback);
59 ///                 return NS_OK;
60 ///             }
61 ///         };
62 ///         let baz = match xpcom::Ensure::ensure(baz) {
63 ///             Ok(val) => val,
64 ///             Err(_) => {
65 ///                 dispatch_pretask_interface_error(BitsTaskError::new(ErrorType::NullArgument, ActionType.into(), ErrorStage::Pretask), callback);
66 ///                 return NS_OK;
67 ///             }
68 ///         };
69 ///         let qux = match xpcom::Ensure::ensure(qux) {
70 ///             Ok(val) => Some(val),
71 ///             Err(_) => None,
72 ///         };
73 ///
74 ///         if let Err(error) = self.rust_method(foo, bar, baz, qux, callback) {
75 ///             dispatch_pretask_interface_error(error, callback);
76 ///         }
77 ///
78 ///         NS_OK
79 ///     }
80 /// ```
81 ///
82 /// Which expects a Rustic implementation method like:
83 ///
84 /// ```ignore
85 ///     fn rust_method(
86 ///         &self,
87 ///         foo: &nsACString,
88 ///         bar: &nsIBar,
89 ///         baz: bool,
90 ///         qux: Option<&nsIQux>,
91 ///         callback: &nsIBitsNewRequestCallback,
92 ///     ) -> Result<(), BitsTaskError> {
93 ///         do_something()
94 ///     }
95 /// ```
96 #[macro_export]
97 macro_rules! nsIBits_method {
98     // The internal rule @ensure_param converts raw pointer arguments to
99     // references, calling dispatch_pretask_interface_error and returning if the
100     // argument is null.
101     // If, however, the type is optional, the reference will also be wrapped
102     // in an option and null pointers will be converted to None.
103     (@ensure_param [optional] $name:ident, $action:expr, $callback:ident) => {
104         let $name = match Ensure::ensure($name) {
105             Ok(val) => Some(val),
106             Err(_) => None,
107         };
108     };
109     (@ensure_param $name:ident, $action:expr, $callback:ident) => {
110         let $name = match Ensure::ensure($name) {
111             Ok(val) => val,
112             Err(_) => {
113                 dispatch_pretask_interface_error(BitsTaskError::new(NullArgument, $action.into(), Pretask), $callback);
114                 return NS_OK;
115             }
116         };
117     };
119     ([$action:expr] $rust_name:ident => $xpcom_name:ident($($([$param_required:ident])* $param_name:ident: $param_type:ty $(,)*)*)) => {
120         #[allow(non_snake_case)]
121         unsafe fn $xpcom_name(&self, $($param_name: $param_type, )* callback: *const nsIBitsNewRequestCallback) -> nsresult {
122             use xpcom::Ensure;
123             use nserror::NS_OK;
124             // When no params are passed, the imports below will not be used, so silence the
125             // warning
126             #[allow(unused_imports)]
127             use bits_interface::{
128                 dispatch_callback::dispatch_pretask_interface_error,
129                 error::{BitsTaskError, ErrorStage::Pretask, ErrorType::NullArgument},
130             };
132             let callback: &nsIBitsNewRequestCallback = match Ensure::ensure(callback) {
133                 Ok(val) => val,
134                 Err(result) => return result,
135             };
136             $(nsIBits_method!(@ensure_param $([$param_required])* $param_name, $action, callback);)*
137             if let Err(error) = self.$rust_name($($param_name, )* callback) {
138                 dispatch_pretask_interface_error(error, callback);
139             }
140             NS_OK
141         }
142     };
146  * Same as above, but expects a nsIBitsCallback as its callback.
147  */
148 #[macro_export]
149 macro_rules! nsIBitsRequest_method {
150     // The internal rule @ensure_param converts raw pointer arguments to
151     // references, calling dispatch_pretask_interface_error and returning if the
152     // argument is null.
153     // If, however, the type is optional, the reference will also be wrapped
154     // in an option and null pointers will be converted to None.
155     (@ensure_param [optional] $name:ident, $action:expr, $callback:ident) => {
156         let $name = match Ensure::ensure($name) {
157             Ok(val) => Some(val),
158             Err(_) => None,
159         };
160     };
161     (@ensure_param $name:ident, $action:expr, $callback:ident) => {
162         let $name = match Ensure::ensure($name) {
163             Ok(val) => val,
164             Err(_) => {
165                 dispatch_pretask_request_error(BitsTaskError::new(NullArgument, $action.into(), Pretask), $callback);
166                 return NS_OK;
167             }
168         };
169     };
171     ([$action:expr] $rust_name:ident => $xpcom_name:ident($($([$param_required:ident])* $param_name:ident: $param_type:ty $(,)*)*)) => {
172         #[allow(non_snake_case)]
173         unsafe fn $xpcom_name(&self, $($param_name: $param_type, )* callback: *const nsIBitsCallback) -> nsresult {
174             use xpcom::Ensure;
175             use nserror::NS_OK;
176             // When no params are passed, the imports below will not be used, so silence the
177             // warning
178             #[allow(unused_imports)]
179             use bits_interface::{
180                 dispatch_callback::dispatch_pretask_request_error,
181                 error::{BitsTaskError, ErrorStage::Pretask, ErrorType::NullArgument},
182             };
184             let callback: &nsIBitsCallback = match Ensure::ensure(callback) {
185                 Ok(val) => val,
186                 Err(result) => return result,
187             };
188             $(nsIBitsRequest_method!(@ensure_param $([$param_required])* $param_name, $action, callback);)*
189             if let Err(error) = self.$rust_name($($param_name, )* callback) {
190                 dispatch_pretask_request_error(error, callback);
191             }
192             NS_OK
193         }
194     };