1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use super::{
MonoClassField, MonoDomain, MonoMethod, MonoObject, MonoType, MonoVTable, mono_handle,
};
use crate::{MonoError, Result, api};
use std::ffi::CString;
mono_handle!(MonoClass);
impl MonoClass {
/// Looks up a field by name on this class.
///
/// # Errors
///
/// Returns [`MonoError::NullByteInName`] if `name` contains an interior null byte.
/// Returns [`MonoError::Uninitialized`] if the Mono API has not been initialized.
pub fn field(self, name: &str) -> Result<Option<MonoClassField>> {
let c_name = CString::new(name).map_err(|_| MonoError::NullByteInName)?;
let ptr = api()?.class_get_field_from_name(self.as_ptr(), c_name.as_ptr());
Ok(MonoClassField::from_ptr(ptr))
}
/// Looks up a method by name on this class.
///
/// `param_count` restricts the search to a specific arity; pass `None` to match any overload.
///
/// # Errors
///
/// Returns [`MonoError::NullByteInName`] if `name` contains an interior null byte.
/// Returns [`MonoError::Uninitialized`] if the Mono API has not been initialized.
pub fn method(self, name: &str, param_count: Option<i32>) -> Result<Option<MonoMethod>> {
let c_name = CString::new(name).map_err(|_| MonoError::NullByteInName)?;
let ptr = api()?.class_get_method_from_name(
self.as_ptr(),
c_name.as_ptr(),
param_count.unwrap_or(-1),
);
Ok(MonoMethod::from_ptr(ptr))
}
/// Returns the [`MonoType`] descriptor for this class.
///
/// # Errors
///
/// Returns [`MonoError::Uninitialized`] if the Mono API has not been initialized.
pub fn mono_type(self) -> Result<Option<MonoType>> {
let ptr = api()?.class_get_type(self.as_ptr());
Ok(MonoType::from_ptr(ptr))
}
/// Returns the vtable for this class in the given domain.
///
/// # Errors
///
/// Returns [`MonoError::Uninitialized`] if the Mono API has not been initialized.
pub fn vtable(self, domain: MonoDomain) -> Result<Option<MonoVTable>> {
let ptr = api()?.class_vtable(domain.as_ptr(), self.as_ptr());
Ok(MonoVTable::from_ptr(ptr))
}
/// Allocates a new uninitialized instance of this class in the given domain.
///
/// The returned object is not yet constructed — call the `.ctor` method via
/// [`MonoMethod::invoke`] to initialize it.
///
/// # Errors
///
/// Returns [`MonoError::Uninitialized`] if the Mono API has not been initialized.
pub fn new_object(self, domain: MonoDomain) -> Result<Option<MonoObject>> {
let ptr = api()?.object_new(domain.as_ptr(), self.as_ptr());
Ok(MonoObject::from_ptr(ptr))
}
/// Returns all fields declared on this class.
///
/// # Errors
///
/// Returns [`MonoError::Uninitialized`] if the Mono API has not been initialized.
pub fn fields(self) -> Result<Vec<MonoClassField>> {
Ok(api()?
.class_get_fields(self.as_ptr())
.into_iter()
.filter_map(MonoClassField::from_ptr)
.collect())
}
/// Returns all methods declared on this class.
///
/// # Errors
///
/// Returns [`MonoError::Uninitialized`] if the Mono API has not been initialized.
pub fn methods(self) -> Result<Vec<MonoMethod>> {
Ok(api()?
.class_get_methods(self.as_ptr())
.into_iter()
.filter_map(MonoMethod::from_ptr)
.collect())
}
}