wrapped_mono/
exception.rs

1use crate::binds::MonoObject;
2use crate::gc::{gc_unsafe_enter, gc_unsafe_exit, GCHandle};
3use crate::{Class, Domain, Image, InteropClass, ObjectTrait};
4use std::ffi::CString;
5/// Safe representation of `MonoException`.
6pub struct Exception {
7    #[cfg(not(feature = "referneced_objects"))]
8    exc_ptr: *mut crate::binds::MonoException,
9    #[cfg(feature = "referneced_objects")]
10    handle: GCHandle,
11}
12impl Exception {
13    /// Raise exception (it can be then catched by catch clause in managed code)
14    /// # Safety
15    /// This function is extremely unsafe, because when it is called, drop functions of local variables **are not** automatically  called.
16    /// # Example
17    /// ## C#
18    ///```csharp
19    /// using System.Runtime.CompilerServices;
20    /// class SomeClass{
21    ///     [MethodImplAttribute(MethodImplOptions.InternalCall)]   
22    ///     void ExceptionThrower();
23    ///     void SomeMethod(){
24    ///         try{
25    ///             ExceptionThrower();
26    ///         }
27    ///         catch(exception){
28    ///             Console.WriteLine("This will always catch exceptions raised in ExceptionThrower");
29    ///         }
30    ///     }
31    /// }
32    ///```
33    /// ## Rust
34    ///```rust
35    /// # use wrapped_mono::{invokable,Exception};
36    /// #[invokable]
37    /// fn exception_thrower(){
38    ///     let some_local_data = vec![12,2,35,32];
39    ///     let exception = Exception::not_implemented("This function will just throw exceptions!");
40    ///     // Everything needs to be dropped before exception is thrown!
41    ///     drop(some_local_data);
42    ///     unsafe{exception.raise()};
43    /// }
44    #[allow(clippy::missing_panics_doc)] // This may never panic, because it is impossible to return from `raise`
45    pub unsafe fn raise(&self) -> ! {
46        unsafe { crate::binds::mono_raise_exception(self.get_ptr().cast()) };
47        panic!("After an exception is thrown, nothing should happen.");
48    }
49    /// Creates [`Exception`] of type *name* in *namespace* from *image* in *domain*'
50    #[must_use]
51    pub fn from_name_domain(
52        domain: &Domain,
53        image: Image,
54        namespace: &str,
55        name: &str,
56    ) -> Option<Self> {
57        let namespace_cstr = CString::new(namespace).expect(crate::STR2CSTR_ERR);
58        let name_cstr = CString::new(name).expect(crate::STR2CSTR_ERR);
59        #[cfg(feature = "referneced_objects")]
60        let marker = gc_unsafe_enter();
61        let res = unsafe {
62            Self::from_ptr(
63                crate::binds::mono_exception_from_name_domain(
64                    domain.get_ptr(),
65                    image.get_ptr(),
66                    namespace_cstr.as_ptr(),
67                    name_cstr.as_ptr(),
68                )
69                .cast(),
70            )
71        };
72        #[cfg(feature = "referneced_objects")]
73        gc_unsafe_exit(marker);
74        let _ = namespace_cstr;
75        let _ = name_cstr;
76        res
77    }
78    /// Creates [`Exception`] of type *name* in *namespace* from *image*
79    #[must_use]
80    pub fn from_name(image: Image, namespace: &str, name: &str) -> Option<Self> {
81        let namespace_cstr = CString::new(namespace).expect(crate::STR2CSTR_ERR);
82        let name_cstr = CString::new(name).expect(crate::STR2CSTR_ERR);
83        #[cfg(feature = "referneced_objects")]
84        let marker = gc_unsafe_enter();
85        let res = unsafe {
86            Self::from_ptr(
87                crate::binds::mono_exception_from_name(
88                    image.get_ptr(),
89                    namespace_cstr.as_ptr(),
90                    name_cstr.as_ptr(),
91                )
92                .cast(),
93            )
94        };
95        #[cfg(feature = "referneced_objects")]
96        gc_unsafe_exit(marker);
97        let _ = namespace_cstr;
98        let _ = name_cstr;
99        res
100    }
101    /// Creates [`Exception`] of type *name* in *namespace* from *image* with message *msg*.
102    #[must_use]
103    pub fn from_name_msg(image: Image, namespace: &str, name: &str, msg: &str) -> Option<Self> {
104        let namespace_cstr = CString::new(namespace).expect(crate::STR2CSTR_ERR);
105        let name_cstr = CString::new(name).expect(crate::STR2CSTR_ERR);
106        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
107        #[cfg(feature = "referneced_objects")]
108        let marker = gc_unsafe_enter();
109        let res = unsafe {
110            Self::from_ptr(
111                crate::binds::mono_exception_from_name_msg(
112                    image.get_ptr(),
113                    namespace_cstr.as_ptr(),
114                    name_cstr.as_ptr(),
115                    msg_cstr.as_ptr(),
116                )
117                .cast(),
118            )
119        };
120        #[cfg(feature = "referneced_objects")]
121        gc_unsafe_exit(marker);
122        let _ = msg_cstr;
123        let _ = namespace_cstr;
124        let _ = name_cstr;
125        res
126    }
127    /// Returns [`Exception`] that is instance of **`System.ArgumentException`**
128    #[must_use]
129    pub fn argument_exception(arg: &str, msg: &str) -> Self {
130        let arg_cstr = CString::new(arg).expect(crate::STR2CSTR_ERR);
131        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
132        #[cfg(feature = "referneced_objects")]
133        let marker = gc_unsafe_enter();
134        let res = unsafe {
135            Self::from_ptr_unchecked(
136                crate::binds::mono_get_exception_argument(arg_cstr.as_ptr(), msg_cstr.as_ptr())
137                    .cast(),
138            )
139        };
140        #[cfg(feature = "referneced_objects")]
141        gc_unsafe_exit(marker);
142        let _ = arg_cstr;
143        let _ = msg_cstr;
144        res
145    }
146    /// Returns [`Exception`] that is instance of **`System.NotImplementedException`**
147    #[must_use]
148    pub fn not_implemented(msg: &str) -> Self {
149        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
150        #[cfg(feature = "referneced_objects")]
151        let marker = gc_unsafe_enter();
152        let res = unsafe {
153            Self::from_ptr_unchecked(
154                crate::binds::mono_get_exception_not_implemented(msg_cstr.as_ptr()).cast(),
155            )
156        };
157        #[cfg(feature = "referneced_objects")]
158        gc_unsafe_exit(marker);
159        let _ = msg_cstr;
160        res
161    }
162    /// Returns [`Exception`] that is instance of **`System.ArgumentNullException`**
163    #[must_use]
164    pub fn argument_null(msg: &str) -> Self {
165        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
166        #[cfg(feature = "referneced_objects")]
167        let marker = gc_unsafe_enter();
168        let res = unsafe {
169            Self::from_ptr_unchecked(
170                crate::binds::mono_get_exception_argument_null(msg_cstr.as_ptr()).cast(),
171            )
172        };
173        #[cfg(feature = "referneced_objects")]
174        gc_unsafe_exit(marker);
175        let _ = msg_cstr;
176        res
177    }
178    /// Returns [`Exception`] that is instance of **`System.ArgumentOutOfRangeException`**
179    #[must_use]
180    pub fn argument_out_of_range(msg: &str) -> Self {
181        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
182        #[cfg(feature = "referneced_objects")]
183        let marker = gc_unsafe_enter();
184        let res = unsafe {
185            Self::from_ptr_unchecked(
186                crate::binds::mono_get_exception_argument_out_of_range(msg_cstr.as_ptr()).cast(),
187            )
188        };
189        #[cfg(feature = "referneced_objects")]
190        gc_unsafe_exit(marker);
191        let _ = msg_cstr;
192        res
193    }
194    /// Returns [`Exception`] that is instance of **`System.ArithmeticException`**
195    #[must_use]
196    pub fn arithmetic() -> Self {
197        #[cfg(feature = "referneced_objects")]
198        let marker = gc_unsafe_enter();
199        let res = unsafe {
200            Self::from_ptr_unchecked(crate::binds::mono_get_exception_arithmetic().cast())
201        };
202        #[cfg(feature = "referneced_objects")]
203        gc_unsafe_exit(marker);
204        res
205    }
206    /// Returns [`Exception`] that is instance of **`System.ArrayTypeMismatchException`**
207    #[must_use]
208    pub fn array_type_mismatch() -> Self {
209        #[cfg(feature = "referneced_objects")]
210        let marker = gc_unsafe_enter();
211        let res = unsafe {
212            Self::from_ptr_unchecked(crate::binds::mono_get_exception_array_type_mismatch().cast())
213        };
214        #[cfg(feature = "referneced_objects")]
215        gc_unsafe_exit(marker);
216        res
217    }
218    /// Returns [`Exception`] that is instance of **`System.BadImageFormatException`**
219    #[must_use]
220    pub fn bad_image_format(msg: &str) -> Self {
221        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
222        #[cfg(feature = "referneced_objects")]
223        let marker = gc_unsafe_enter();
224        let res = unsafe {
225            Self::from_ptr_unchecked(
226                crate::binds::mono_get_exception_bad_image_format(msg_cstr.as_ptr()).cast(),
227            )
228        };
229        #[cfg(feature = "referneced_objects")]
230        gc_unsafe_exit(marker);
231        let _ = msg_cstr;
232        res
233    }
234    /// Returns [`Exception`] that is instance of **`System.CannotUnloadAppdomain`**
235    #[must_use]
236    pub fn cannot_unload_appdomain(msg: &str) -> Self {
237        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
238        #[cfg(feature = "referneced_objects")]
239        let marker = gc_unsafe_enter();
240        let res = unsafe {
241            Self::from_ptr_unchecked(
242                crate::binds::mono_get_exception_cannot_unload_appdomain(msg_cstr.as_ptr()).cast(),
243            )
244        };
245        #[cfg(feature = "referneced_objects")]
246        gc_unsafe_exit(marker);
247        let _ = msg_cstr;
248        res
249    }
250    /// Returns [`Exception`] that is instance of **`System.AppDomainUnloadedException`**
251    #[must_use]
252    pub fn domain_unloaded() -> Self {
253        #[cfg(feature = "referneced_objects")]
254        let marker = gc_unsafe_enter();
255        let res = unsafe {
256            Self::from_ptr_unchecked(crate::binds::mono_get_exception_appdomain_unloaded().cast())
257        };
258        #[cfg(feature = "referneced_objects")]
259        gc_unsafe_exit(marker);
260        res
261    }
262    /// Returns [`Exception`] that is instance of **`System.DivideByZeroException`**
263    #[must_use]
264    pub fn divide_by_zero() -> Self {
265        #[cfg(feature = "referneced_objects")]
266        let marker = gc_unsafe_enter();
267        let res = unsafe {
268            Self::from_ptr_unchecked(crate::binds::mono_get_exception_divide_by_zero().cast())
269        };
270        #[cfg(feature = "referneced_objects")]
271        gc_unsafe_exit(marker);
272        res
273    }
274    /// Returns [`Exception`] that is instance of **`System.ExecutionEngineException`**
275    #[must_use]
276    pub fn execution_engine_exception(msg: &str) -> Self {
277        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
278        #[cfg(feature = "referneced_objects")]
279        let marker = gc_unsafe_enter();
280        let res = unsafe {
281            Self::from_ptr_unchecked(
282                crate::binds::mono_get_exception_execution_engine(msg_cstr.as_ptr()).cast(),
283            )
284        };
285        #[cfg(feature = "referneced_objects")]
286        gc_unsafe_exit(marker);
287        let _ = msg_cstr;
288        res
289    }
290    /// Returns [`Exception`] that is instance of **`System.IO.FileNotFoundException`**
291    #[must_use]
292    pub fn file_not_found(fname: &str) -> Self {
293        let fname_cstr = CString::new(fname).expect(crate::STR2CSTR_ERR);
294        let ms = unsafe { crate::binds::mono_string_new_wrapper(fname_cstr.as_ptr()) };
295        let _ = fname_cstr;
296        #[cfg(feature = "referneced_objects")]
297        let marker = gc_unsafe_enter();
298        let res = unsafe {
299            Self::from_ptr_unchecked(crate::binds::mono_get_exception_file_not_found(ms).cast())
300        };
301        #[cfg(feature = "referneced_objects")]
302        gc_unsafe_exit(marker);
303        res
304    }
305    /// Returns [`Exception`] that is instance of **`System.IndexOutOfRangeException`**
306    #[must_use]
307    pub fn index_out_of_range() -> Self {
308        #[cfg(feature = "referneced_objects")]
309        let marker = gc_unsafe_enter();
310        let res = unsafe {
311            Self::from_ptr_unchecked(crate::binds::mono_get_exception_index_out_of_range().cast())
312        };
313        #[cfg(feature = "referneced_objects")]
314        gc_unsafe_exit(marker);
315        res
316    }
317    /// Returns [`Exception`] that is instance of **`System.InvalidCastException`**
318    #[must_use]
319    pub fn invald_cast() -> Self {
320        #[cfg(feature = "referneced_objects")]
321        let marker = gc_unsafe_enter();
322        let res = unsafe {
323            Self::from_ptr_unchecked(crate::binds::mono_get_exception_invalid_cast().cast())
324        };
325        #[cfg(feature = "referneced_objects")]
326        gc_unsafe_exit(marker);
327        res
328    }
329    /// Returns [`Exception`] that is instance of **`System.IO.IOException`**
330    #[must_use]
331    pub fn io_exception(msg: &str) -> Self {
332        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
333        #[cfg(feature = "referneced_objects")]
334        let marker = gc_unsafe_enter();
335        let res = unsafe {
336            Self::from_ptr_unchecked(crate::binds::mono_get_exception_io(msg_cstr.as_ptr()).cast())
337        };
338        #[cfg(feature = "referneced_objects")]
339        gc_unsafe_exit(marker);
340        let _ = msg_cstr;
341        res
342    }
343    /// Returns [`Exception`] that is instance of **`System.MissingMethodException`**
344    #[must_use]
345    pub fn missing_method(class_name: &str, member_name: &str) -> Self {
346        let class_name_cstr = CString::new(class_name).expect(crate::STR2CSTR_ERR);
347        let member_name_cstr = CString::new(member_name).expect(crate::STR2CSTR_ERR);
348        #[cfg(feature = "referneced_objects")]
349        let marker = gc_unsafe_enter();
350        let res = unsafe {
351            Self::from_ptr_unchecked(
352                crate::binds::mono_get_exception_missing_method(
353                    class_name_cstr.as_ptr(),
354                    member_name_cstr.as_ptr(),
355                )
356                .cast(),
357            )
358        };
359        #[cfg(feature = "referneced_objects")]
360        gc_unsafe_exit(marker);
361        let _ = class_name_cstr;
362        let _ = member_name_cstr;
363        res
364    }
365    /// Returns [`Exception`] that is instance of **`System.NullReferenceException`**
366    #[must_use]
367    pub fn null_reference() -> Self {
368        #[cfg(feature = "referneced_objects")]
369        let marker = gc_unsafe_enter();
370        let res = unsafe {
371            Self::from_ptr_unchecked(crate::binds::mono_get_exception_null_reference().cast())
372        };
373        #[cfg(feature = "referneced_objects")]
374        gc_unsafe_exit(marker);
375        res
376    }
377    /// Returns [`Exception`] that is instance of **`System.OverflowException`**
378    #[must_use]
379    pub fn overflow() -> Self {
380        #[cfg(feature = "referneced_objects")]
381        let marker = gc_unsafe_enter();
382        let res =
383            unsafe { Self::from_ptr_unchecked(crate::binds::mono_get_exception_overflow().cast()) };
384        #[cfg(feature = "referneced_objects")]
385        gc_unsafe_exit(marker);
386        res
387    }
388    /// Returns [`Exception`] that is instance of **`System.Security.SecurityException`**
389    #[must_use]
390    pub fn security() -> Self {
391        #[cfg(feature = "referneced_objects")]
392        let marker = gc_unsafe_enter();
393        let res =
394            unsafe { Self::from_ptr_unchecked(crate::binds::mono_get_exception_security().cast()) };
395        #[cfg(feature = "referneced_objects")]
396        gc_unsafe_exit(marker);
397        res
398    }
399    /// Returns [`Exception`] that is instance of **`System.Runtime.Serialization.SerializationException`**
400    #[must_use]
401    pub fn serialization_exception(msg: &str) -> Self {
402        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
403        #[cfg(feature = "referneced_objects")]
404        let marker = gc_unsafe_enter();
405        let res = unsafe {
406            Self::from_ptr_unchecked(
407                crate::binds::mono_get_exception_serialization(msg_cstr.as_ptr()).cast(),
408            )
409        };
410        #[cfg(feature = "referneced_objects")]
411        gc_unsafe_exit(marker);
412        let _ = msg_cstr;
413        res
414    }
415    /// Returns [`Exception`] that is instance of **`System.StackOverflowException`**
416    #[must_use]
417    pub fn stack_overflow() -> Self {
418        #[cfg(feature = "referneced_objects")]
419        let marker = gc_unsafe_enter();
420        let res = unsafe {
421            Self::from_ptr_unchecked(crate::binds::mono_get_exception_stack_overflow().cast())
422        };
423        #[cfg(feature = "referneced_objects")]
424        gc_unsafe_exit(marker);
425        res
426    }
427    /// Returns [`Exception`] that is instance of **`System.SynchronizationLockException`**
428    #[must_use]
429    pub fn synchronization_lock(msg: &str) -> Self {
430        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
431        #[cfg(feature = "referneced_objects")]
432        let marker = gc_unsafe_enter();
433        let res = unsafe {
434            Self::from_ptr_unchecked(
435                crate::binds::mono_get_exception_synchronization_lock(msg_cstr.as_ptr()).cast(),
436            )
437        };
438        #[cfg(feature = "referneced_objects")]
439        gc_unsafe_exit(marker);
440        let _ = msg_cstr;
441        res
442    }
443    /// Returns [`Exception`] that is instance of **`System.Threading.ThreadAbortException`**
444    #[must_use]
445    pub fn thread_abort() -> Self {
446        #[cfg(feature = "referneced_objects")]
447        let marker = gc_unsafe_enter();
448        let res = unsafe {
449            Self::from_ptr_unchecked(crate::binds::mono_get_exception_thread_abort().cast())
450        };
451        #[cfg(feature = "referneced_objects")]
452        gc_unsafe_exit(marker);
453        res
454    }
455    /// Returns [`Exception`] that is instance of **`System.Threading.ThreadStateException`**
456    #[must_use]
457    pub fn thread_sate(msg: &str) -> Self {
458        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
459        #[cfg(feature = "referneced_objects")]
460        let marker = gc_unsafe_enter();
461        let res = unsafe {
462            Self::from_ptr_unchecked(
463                crate::binds::mono_get_exception_thread_state(msg_cstr.as_ptr()).cast(),
464            )
465        };
466        #[cfg(feature = "referneced_objects")]
467        gc_unsafe_exit(marker);
468        let _ = msg_cstr;
469        res
470    }
471    /// Returns [`Exception`] that is instance of **`System.TypeInitializationException`** with *`type_name`* and inner exception *`inner`*.
472    #[must_use]
473    pub fn type_initialization(type_name: &str, inner: &Self) -> Self {
474        let type_name_cstr = CString::new(type_name).expect(crate::STR2CSTR_ERR);
475        #[cfg(feature = "referneced_objects")]
476        let marker = gc_unsafe_enter();
477        let res = unsafe {
478            Self::from_ptr_unchecked(
479                crate::binds::mono_get_exception_type_initialization(
480                    type_name_cstr.as_ptr(),
481                    inner.get_ptr().cast(),
482                )
483                .cast(),
484            )
485        };
486        #[cfg(feature = "referneced_objects")]
487        gc_unsafe_exit(marker);
488        let _ = type_name_cstr;
489        res
490    }
491    /// Returns [`Exception`] that is instance of **`System.TypeLoadException`**
492    #[must_use]
493    pub fn type_load(class_name: &str, member_name: &str) -> Self {
494        let class_name_cstr = CString::new(class_name).expect(crate::STR2CSTR_ERR);
495        #[cfg(feature = "referneced_objects")]
496        let marker = gc_unsafe_enter();
497        let cn_mono_string =
498            unsafe { crate::binds::mono_string_new_wrapper(class_name_cstr.as_ptr()) };
499        let _ = class_name_cstr;
500        let member_name_cstr = CString::new(member_name).expect(crate::STR2CSTR_ERR);
501        let res = unsafe {
502            Self::from_ptr_unchecked(
503                crate::binds::mono_get_exception_type_load(
504                    cn_mono_string,
505                    member_name_cstr.as_ptr() as *mut i8,
506                )
507                .cast(),
508            )
509        };
510        #[cfg(feature = "referneced_objects")]
511        gc_unsafe_exit(marker);
512        let _ = member_name_cstr;
513        res
514    }
515    /// Returns [`Exception`] that is instance of **`System.InvalidOperationException`**
516    #[must_use]
517    pub fn invalid_operation(msg: &str) -> Self {
518        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
519        #[cfg(feature = "referneced_objects")]
520        let marker = gc_unsafe_enter();
521        let res = unsafe {
522            Self::from_ptr_unchecked(
523                crate::binds::mono_get_exception_invalid_operation(msg_cstr.as_ptr()).cast(),
524            )
525        };
526        #[cfg(feature = "referneced_objects")]
527        gc_unsafe_exit(marker);
528        let _ = msg_cstr;
529        res
530    }
531    /// Returns [`Exception`] that is instance of **`System.MissingFieldException`**
532    #[must_use]
533    pub fn missing_field(class_name: &str, member_name: &str) -> Self {
534        let class_name_cstr = CString::new(class_name).expect(crate::STR2CSTR_ERR);
535        let member_name_cstr = CString::new(member_name).expect(crate::STR2CSTR_ERR);
536        #[cfg(feature = "referneced_objects")]
537        let marker = gc_unsafe_enter();
538        let res = unsafe {
539            Self::from_ptr_unchecked(
540                crate::binds::mono_get_exception_missing_field(
541                    class_name_cstr.as_ptr(),
542                    member_name_cstr.as_ptr() as *mut i8,
543                )
544                .cast(),
545            )
546        };
547        #[cfg(feature = "referneced_objects")]
548        gc_unsafe_exit(marker);
549        let _ = member_name_cstr;
550        let _ = class_name_cstr;
551        res
552    }
553    /// Returns [`Exception`] that is instance of **`System.NotSupportedException`**
554    #[must_use]
555    pub fn not_supported(msg: &str) -> Self {
556        let msg_cstr = CString::new(msg).expect(crate::STR2CSTR_ERR);
557        #[cfg(feature = "referneced_objects")]
558        let marker = gc_unsafe_enter();
559        let res = unsafe {
560            Self::from_ptr_unchecked(
561                crate::binds::mono_get_exception_not_supported(msg_cstr.as_ptr()).cast(),
562            )
563        };
564        #[cfg(feature = "referneced_objects")]
565        gc_unsafe_exit(marker);
566        let _ = msg_cstr;
567        res
568    }
569    /// Returns [`Exception`] that is instance of **`System.FieldAccessException`**
570    #[must_use]
571    pub fn field_access() -> Self {
572        #[cfg(feature = "referneced_objects")]
573        let marker = gc_unsafe_enter();
574        let res = unsafe {
575            Self::from_ptr_unchecked(crate::binds::mono_get_exception_field_access().cast())
576        };
577        #[cfg(feature = "referneced_objects")]
578        gc_unsafe_exit(marker);
579        res
580    }
581    /// Returns [`Exception`] that is instance of **`System.MethodAccessException`**
582    #[must_use]
583    pub fn method_access() -> Self {
584        #[cfg(feature = "referneced_objects")]
585        let marker = gc_unsafe_enter();
586        let res = unsafe {
587            Self::from_ptr_unchecked(crate::binds::mono_get_exception_method_access().cast())
588        };
589        #[cfg(feature = "referneced_objects")]
590        gc_unsafe_exit(marker);
591        res
592    }
593    /// Returns [`Exception`] that is instance of **`System.OutOfMemoryException`**
594    #[must_use]
595    pub fn out_of_memory() -> Self {
596        #[cfg(feature = "referneced_objects")]
597        let marker = gc_unsafe_enter();
598        let res = unsafe {
599            Self::from_ptr_unchecked(crate::binds::mono_get_exception_out_of_memory().cast())
600        };
601        #[cfg(feature = "referneced_objects")]
602        gc_unsafe_exit(marker);
603        res
604    }
605    /// Creates [`Exception`] with a wraped inner [`Exception`] *inner*.
606    #[must_use]
607    pub fn wrapped(inner: &Self) -> Self {
608        #[cfg(feature = "referneced_objects")]
609        let marker = gc_unsafe_enter();
610        let res = unsafe {
611            Self::from_ptr_unchecked(
612                crate::binds::mono_get_exception_runtime_wrapped(inner.get_ptr().cast()).cast(),
613            )
614        };
615        #[cfg(feature = "referneced_objects")]
616        gc_unsafe_exit(marker);
617        res
618    }
619}
620/// Variant of except which instead of panicking will raise a managed exception.
621pub(crate) fn except_managed<T: Sized>(option: Option<T>, msg: &str) -> T {
622    option.map_or_else(
623        || {
624            let exc = Exception::argument_null(&format!(
625                "Value of type: \"{}\" was null!\"{}\"",
626                std::any::type_name::<T>(),
627                &msg
628            ));
629            unsafe {
630                exc.raise();
631            }
632        },
633        |t| t,
634    )
635}
636/*
637/// Variant of except which instead of panicking will raise a managed exception.
638pub(crate) fn unwrap_managed<T: Sized>(option: Option<T>) -> T {
639    if let Some(t) = option {
640        t
641    } else {
642        let exc = Exception::argument_null(&format!(
643            "Value of type: \"{}\" was null!",
644            std::any::type_name::<T>()
645        ));
646        unsafe{exc.raise();}
647    }
648}*/
649use core::fmt::Formatter;
650impl core::fmt::Debug for Exception {
651    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
652        let mstr = self
653            .to_mstring()
654            .expect("Got an exception while trying to convert an exception to string!")
655            .expect(
656                "Got null instead of a string while trying to convert an exception to a string!",
657            )
658            .to_string();
659        write!(f, "Exception:\"{mstr}\"")
660    }
661}
662impl crate::object::ObjectTrait for Exception {
663    #[must_use]
664    unsafe fn from_ptr_unchecked(exc_ptr: *mut MonoObject) -> Self {
665        #[cfg(not(feature = "referneced_objects"))]
666        {
667            Self {
668                exc_ptr: exc_ptr.cast(),
669            }
670        }
671        #[cfg(feature = "referneced_objects")]
672        {
673            Self {
674                handle: GCHandle::create_default(exc_ptr.cast()),
675            }
676        }
677    }
678    #[must_use]
679    fn get_ptr(&self) -> *mut MonoObject {
680        #[cfg(not(feature = "referneced_objects"))]
681        {
682            self.exc_ptr.cast()
683        }
684        #[cfg(feature = "referneced_objects")]
685        {
686            self.handle.get_target().cast()
687        }
688    }
689}
690impl InteropClass for Exception {
691    fn get_mono_class() -> Class {
692        Class::get_exception_class()
693    }
694}
695impl Clone for Exception {
696    fn clone(&self) -> Self {
697        unsafe { Self::from_ptr_unchecked(self.get_ptr().cast()) } //If exception exists then it can't be null
698    }
699}
700impl<O: ObjectTrait> PartialEq<O> for Exception {
701    fn eq(&self, other: &O) -> bool {
702        self.get_ptr().cast() == other.get_ptr()
703    }
704}
705impl std::fmt::Display for Exception {
706    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
707        let mstr = self.to_mstring();
708        write!(
709            f,
710            "{}",
711            mstr.expect("Got an exception while converting an exception String!")
712                .expect("Got null from converting exception to string!")
713                .to_string()
714        )
715    }
716}