1use thiserror::Error;
4
5pub type Result<T> = std::result::Result<T, MonoError>;
6
7#[derive(Debug, Error)]
8pub enum MonoError {
9 #[error("DLL `{0}` not found")]
10 DllNotFound(String),
11 #[error("Export not found in DLL: `{0}`")]
12 FnNotFound(&'static str),
13 #[error("Mono API already initialized! Multiple calls to `mono::init()` are not necessary.")]
14 AlreadyInitialized,
15 #[error("Mono API not initialized! Call `mono::init()` first.")]
16 Uninitialized,
17 #[error("string argument contains an interior null byte")]
18 NullByteInName,
19 #[error("managed exception was thrown during method invocation")]
20 ManagedException(crate::MonoObject),
21}
22
23#[cfg(test)]
24mod tests {
25 use std::error::Error;
26
27 use super::MonoError;
28 use crate::MonoObject;
29
30 #[test]
31 fn dll_not_found_display() {
32 let e = MonoError::DllNotFound("mono.dll".to_owned());
33 assert_eq!(e.to_string(), "DLL `mono.dll` not found");
34 }
35
36 #[test]
37 fn fn_not_found_display() {
38 let e = MonoError::FnNotFound("mono_get_root_domain");
39 assert_eq!(
40 e.to_string(),
41 "Export not found in DLL: `mono_get_root_domain`"
42 );
43 }
44
45 #[test]
46 fn already_initialized_display() {
47 let e = MonoError::AlreadyInitialized;
48 assert!(e.to_string().contains("already initialized"));
49 }
50
51 #[test]
52 fn uninitialized_display() {
53 let e = MonoError::Uninitialized;
54 assert!(e.to_string().contains("not initialized"));
55 }
56
57 #[test]
58 fn null_byte_in_name_display() {
59 let e = MonoError::NullByteInName;
60 assert_eq!(
61 e.to_string(),
62 "string argument contains an interior null byte"
63 );
64 }
65
66 #[test]
67 fn managed_exception_display() {
68 let obj = unsafe { MonoObject::from_ptr_unchecked(std::ptr::dangling_mut()) };
69 let e = MonoError::ManagedException(obj);
70 assert_eq!(
71 e.to_string(),
72 "managed exception was thrown during method invocation"
73 );
74 }
75
76 #[test]
77 fn implements_std_error_trait() {
78 let e: Box<dyn Error> = Box::new(MonoError::Uninitialized);
79 assert!(e.source().is_none());
80 }
81
82 #[test]
83 fn dll_not_found_debug_contains_variant_name() {
84 let e = MonoError::DllNotFound("x.dll".to_owned());
85 assert!(format!("{e:?}").contains("DllNotFound"));
86 }
87
88 #[test]
89 fn fn_not_found_debug_contains_variant_name() {
90 let e = MonoError::FnNotFound("some_export");
91 assert!(format!("{e:?}").contains("FnNotFound"));
92 }
93}