Skip to main content

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