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