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::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}