mono_rs/
class.rs

1use std::{
2    ffi::{c_void, CStr, CString},
3    sync::Arc,
4};
5
6use crate::{
7    assembly::Assembly,
8    bindings::{
9        mono_class_get_name, mono_method_desc_new, mono_method_desc_search_in_class,
10        mono_object_new, MonoClass,
11    },
12    domain::Domain,
13    image::Image,
14    method::ClassMethod,
15    object::Object,
16    void::AsRawVoid,
17    MonoResult,
18};
19
20#[derive(Clone, Debug)]
21pub struct Class {
22    pub mono_ptr: *mut MonoClass,
23    pub assembly: Arc<Assembly>,
24    pub domain: Arc<Domain>,
25    pub image: Arc<Image>,
26}
27
28impl Class {
29    pub fn create_object(&self) -> MonoResult<Object> {
30        let mono_ptr = unsafe { mono_object_new(self.domain.mono_ptr, self.mono_ptr) };
31
32        if mono_ptr.is_null() {
33            return Err("MonoObject Null Error!".into());
34        }
35
36        Ok(Object {
37            mono_ptr,
38            assembly: self.assembly.clone(),
39            class: Arc::new(self.clone()),
40            domain: self.domain.clone(),
41            image: self.image.clone(),
42        })
43    }
44
45    pub fn get_name(&self) -> String {
46        unsafe {
47            CStr::from_ptr(mono_class_get_name(self.mono_ptr))
48                .to_string_lossy()
49                .to_string()
50        }
51    }
52
53    pub fn get_method_by_name(&self, name: &'static str) -> MonoResult<ClassMethod> {
54        let class_name = self.get_name();
55        let method_name = CString::new(format!("{}:{}()", class_name, name))?;
56        let mono_method_desc = unsafe { mono_method_desc_new(method_name.as_ptr(), 0) };
57
58        if mono_method_desc.is_null() {
59            return Err("MonoMethodDecs Null Error!".into());
60        }
61
62        let mono_ptr =
63            unsafe { mono_method_desc_search_in_class(mono_method_desc, self.mono_ptr) };
64
65        if mono_ptr.is_null() {
66            return Err("MonoMethod Null Error!".into());
67        }
68
69        Ok(ClassMethod {
70            mono_ptr,
71            assembly: self.assembly.clone(),
72            class: Arc::new(self.clone()),
73            domain: self.domain.clone(),
74            image: self.image.clone(),
75        })
76    }
77}
78
79impl AsRawVoid for Class {
80    fn as_raw_void(self) -> *mut c_void {
81        self.mono_ptr as *mut c_void
82    }
83}