mtl_gpu/mtl4/
library_function_descriptor.rs1use std::ffi::c_void;
6use std::ptr::NonNull;
7
8use mtl_foundation::Referencing;
9use mtl_sys::{msg_send_0, msg_send_1, sel};
10
11use crate::Library;
12
13#[repr(transparent)]
24pub struct LibraryFunctionDescriptor(NonNull<c_void>);
25
26impl LibraryFunctionDescriptor {
27 #[inline]
29 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
30 NonNull::new(ptr).map(Self)
31 }
32
33 #[inline]
35 pub fn as_raw(&self) -> *mut c_void {
36 self.0.as_ptr()
37 }
38
39 pub fn new() -> Option<Self> {
41 unsafe {
42 let class = mtl_sys::Class::get("MTL4LibraryFunctionDescriptor")?;
43 let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
44 if ptr.is_null() {
45 return None;
46 }
47 let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
48 Self::from_raw(ptr)
49 }
50 }
51
52 pub fn library(&self) -> Option<Library> {
56 unsafe {
57 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(library));
58 Library::from_raw(ptr)
59 }
60 }
61
62 pub fn set_library(&self, library: &Library) {
66 unsafe {
67 let _: () = msg_send_1(self.as_ptr(), sel!(setLibrary:), library.as_ptr());
68 }
69 }
70
71 pub fn name(&self) -> Option<String> {
75 unsafe {
76 let ns_string: *mut c_void = msg_send_0(self.as_ptr(), sel!(name));
77 if ns_string.is_null() {
78 return None;
79 }
80 let c_str: *const i8 = msg_send_0(ns_string, sel!(UTF8String));
81 if c_str.is_null() {
82 return None;
83 }
84 Some(
85 std::ffi::CStr::from_ptr(c_str)
86 .to_string_lossy()
87 .into_owned(),
88 )
89 }
90 }
91
92 pub fn set_name(&self, name: &str) {
96 if let Some(ns_name) = mtl_foundation::String::from_str(name) {
97 unsafe {
98 let _: () = msg_send_1(self.as_ptr(), sel!(setName:), ns_name.as_ptr());
99 }
100 }
101 }
102}
103
104impl Default for LibraryFunctionDescriptor {
105 fn default() -> Self {
106 Self::new().expect("Failed to create MTL4LibraryFunctionDescriptor")
107 }
108}
109
110impl Clone for LibraryFunctionDescriptor {
111 fn clone(&self) -> Self {
112 unsafe {
113 mtl_sys::msg_send_0::<*mut c_void>(self.as_ptr(), mtl_sys::sel!(retain));
114 }
115 Self(self.0)
116 }
117}
118
119impl Drop for LibraryFunctionDescriptor {
120 fn drop(&mut self) {
121 unsafe {
122 mtl_sys::msg_send_0::<()>(self.as_ptr(), mtl_sys::sel!(release));
123 }
124 }
125}
126
127impl Referencing for LibraryFunctionDescriptor {
128 #[inline]
129 fn as_ptr(&self) -> *const c_void {
130 self.0.as_ptr()
131 }
132}
133
134unsafe impl Send for LibraryFunctionDescriptor {}
135unsafe impl Sync for LibraryFunctionDescriptor {}
136
137impl std::fmt::Debug for LibraryFunctionDescriptor {
138 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
139 f.debug_struct("LibraryFunctionDescriptor")
140 .field("name", &self.name())
141 .finish()
142 }
143}
144
145#[cfg(test)]
146mod tests {
147 use super::*;
148
149 #[test]
150 fn test_library_function_descriptor_size() {
151 assert_eq!(
152 std::mem::size_of::<LibraryFunctionDescriptor>(),
153 std::mem::size_of::<*mut c_void>()
154 );
155 }
156}