Skip to main content

mtl_gpu/argument/
struct_member.rs

1//! A member of a struct type.
2
3use std::ffi::c_void;
4use std::ptr::NonNull;
5
6use mtl_foundation::{Referencing, UInteger};
7use mtl_sys::{msg_send_0, sel};
8
9use crate::enums::DataType;
10
11use super::{ArrayType, PointerType, StructType, TensorReferenceType, TextureReferenceType};
12
13/// A member of a struct type.
14///
15/// C++ equivalent: `MTL::StructMember`
16#[repr(transparent)]
17pub struct StructMember(pub(crate) NonNull<c_void>);
18
19impl StructMember {
20    /// Create from a raw pointer.
21    ///
22    /// # Safety
23    ///
24    /// The pointer must be a valid Metal StructMember.
25    #[inline]
26    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
27        NonNull::new(ptr).map(Self)
28    }
29
30    /// Get the raw pointer.
31    #[inline]
32    pub fn as_raw(&self) -> *mut c_void {
33        self.0.as_ptr()
34    }
35
36    /// Get the argument index.
37    ///
38    /// C++ equivalent: `NS::UInteger argumentIndex() const`
39    #[inline]
40    pub fn argument_index(&self) -> UInteger {
41        unsafe { msg_send_0(self.as_ptr(), sel!(argumentIndex)) }
42    }
43
44    /// Get the data type.
45    ///
46    /// C++ equivalent: `DataType dataType() const`
47    #[inline]
48    pub fn data_type(&self) -> DataType {
49        unsafe { msg_send_0(self.as_ptr(), sel!(dataType)) }
50    }
51
52    /// Get the name.
53    ///
54    /// C++ equivalent: `NS::String* name() const`
55    pub fn name(&self) -> Option<String> {
56        unsafe {
57            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(name));
58            if ptr.is_null() {
59                return None;
60            }
61            let utf8_ptr: *const std::ffi::c_char =
62                mtl_sys::msg_send_0(ptr as *const c_void, sel!(UTF8String));
63            if utf8_ptr.is_null() {
64                return None;
65            }
66            let c_str = std::ffi::CStr::from_ptr(utf8_ptr);
67            Some(c_str.to_string_lossy().into_owned())
68        }
69    }
70
71    /// Get the offset.
72    ///
73    /// C++ equivalent: `NS::UInteger offset() const`
74    #[inline]
75    pub fn offset(&self) -> UInteger {
76        unsafe { msg_send_0(self.as_ptr(), sel!(offset)) }
77    }
78
79    /// Get the array type (if this member is an array).
80    ///
81    /// C++ equivalent: `ArrayType* arrayType()`
82    pub fn array_type(&self) -> Option<ArrayType> {
83        unsafe {
84            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(arrayType));
85            ArrayType::from_raw(ptr)
86        }
87    }
88
89    /// Get the pointer type (if this member is a pointer).
90    ///
91    /// C++ equivalent: `PointerType* pointerType()`
92    pub fn pointer_type(&self) -> Option<PointerType> {
93        unsafe {
94            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(pointerType));
95            PointerType::from_raw(ptr)
96        }
97    }
98
99    /// Get the struct type (if this member is a struct).
100    ///
101    /// C++ equivalent: `StructType* structType()`
102    pub fn struct_type(&self) -> Option<StructType> {
103        unsafe {
104            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(structType));
105            StructType::from_raw(ptr)
106        }
107    }
108
109    /// Get the texture reference type (if this member is a texture).
110    ///
111    /// C++ equivalent: `TextureReferenceType* textureReferenceType()`
112    pub fn texture_reference_type(&self) -> Option<TextureReferenceType> {
113        unsafe {
114            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(textureReferenceType));
115            TextureReferenceType::from_raw(ptr)
116        }
117    }
118
119    /// Get the tensor reference type (if this member is a tensor).
120    ///
121    /// C++ equivalent: `TensorReferenceType* tensorReferenceType()`
122    pub fn tensor_reference_type(&self) -> Option<TensorReferenceType> {
123        unsafe {
124            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(tensorReferenceType));
125            TensorReferenceType::from_raw(ptr)
126        }
127    }
128}
129
130impl Clone for StructMember {
131    fn clone(&self) -> Self {
132        unsafe {
133            msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
134        }
135        Self(self.0)
136    }
137}
138
139impl Drop for StructMember {
140    fn drop(&mut self) {
141        unsafe {
142            msg_send_0::<()>(self.as_ptr(), sel!(release));
143        }
144    }
145}
146
147impl Referencing for StructMember {
148    #[inline]
149    fn as_ptr(&self) -> *const c_void {
150        self.0.as_ptr()
151    }
152}
153
154unsafe impl Send for StructMember {}
155unsafe impl Sync for StructMember {}