Skip to main content

modelio/
asset_resolver.rs

1use std::ptr;
2
3use crate::asset::Asset;
4use crate::error::Result;
5use crate::ffi;
6use crate::handle::ObjectHandle;
7use crate::util::{c_string, required_handle, take_string};
8
9#[derive(Debug, Clone)]
10/// Wraps the corresponding Model I/O asset resolver counterpart.
11pub struct AssetResolver {
12    handle: ObjectHandle,
13}
14
15impl AssetResolver {
16    /// Builds this wrapper from the retained handle of the wrapped Model I/O asset resolver counterpart.
17    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
18        Self { handle }
19    }
20
21    /// Returns the opaque pointer used to call the wrapped Model I/O asset resolver counterpart.
22    pub(crate) fn as_ptr(&self) -> *mut core::ffi::c_void {
23        self.handle.as_ptr()
24    }
25
26    /// Calls the corresponding Model I/O method on the wrapped Model I/O asset resolver counterpart.
27    pub fn can_resolve_asset_named(&self, name: &str) -> Result<bool> {
28        let name = c_string(name)?;
29        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
30        Ok(unsafe { ffi::mdl_asset_resolver_can_resolve_named(self.as_ptr(), name.as_ptr()) != 0 })
31    }
32
33    /// Calls the corresponding Model I/O method on the wrapped Model I/O asset resolver counterpart.
34    pub fn resolve_asset_named(&self, name: &str) -> Result<Option<String>> {
35        let name = c_string(name)?;
36        // SAFETY: The unsafe operation is valid in this context.
37        Ok(take_string(unsafe {
38            ffi::mdl_asset_resolver_resolve_named(self.as_ptr(), name.as_ptr())
39        }))
40    }
41}
42
43#[derive(Debug, Clone)]
44/// Wraps the corresponding Model I/O path asset resolver counterpart.
45pub struct PathAssetResolver {
46    handle: ObjectHandle,
47}
48
49impl PathAssetResolver {
50    /// Builds this wrapper from the retained handle of the wrapped Model I/O path asset resolver counterpart.
51    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
52        Self { handle }
53    }
54
55    /// Wraps the corresponding Model I/O initializer for the wrapped Model I/O path asset resolver counterpart.
56    pub fn new(path: &str) -> Result<Self> {
57        let path = c_string(path)?;
58        let mut out_resolver = ptr::null_mut();
59        let mut out_error = ptr::null_mut();
60        // SAFETY: The unsafe operation is valid in this context.
61        let status = unsafe {
62            ffi::mdl_path_asset_resolver_new(path.as_ptr(), &mut out_resolver, &mut out_error)
63        };
64        crate::util::status_result(status, out_error)?;
65        Ok(Self::from_handle(required_handle(
66            out_resolver,
67            "MDLPathAssetResolver",
68        )?))
69    }
70
71    #[must_use]
72    /// Calls the corresponding Model I/O method on the wrapped Model I/O path asset resolver counterpart.
73    pub fn path(&self) -> Option<String> {
74        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
75        take_string(unsafe { ffi::mdl_path_asset_resolver_path(self.handle.as_ptr()) })
76    }
77
78    /// Calls the corresponding Model I/O method on the wrapped Model I/O path asset resolver counterpart.
79    pub fn set_path(&self, path: &str) -> Result<()> {
80        let path = c_string(path)?;
81        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
82        unsafe { ffi::mdl_path_asset_resolver_set_path(self.handle.as_ptr(), path.as_ptr()) };
83        Ok(())
84    }
85
86    #[must_use]
87    /// Calls the corresponding Model I/O method on the wrapped Model I/O path asset resolver counterpart.
88    pub fn as_asset_resolver(&self) -> AssetResolver {
89        AssetResolver::from_handle(self.handle.clone())
90    }
91}
92
93#[derive(Debug, Clone)]
94/// Wraps the corresponding Model I/O bundle asset resolver counterpart.
95pub struct BundleAssetResolver {
96    handle: ObjectHandle,
97}
98
99impl BundleAssetResolver {
100    /// Builds this wrapper from the retained handle of the wrapped Model I/O bundle asset resolver counterpart.
101    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
102        Self { handle }
103    }
104
105    /// Wraps the corresponding Model I/O initializer for the wrapped Model I/O bundle asset resolver counterpart.
106    pub fn new(path: &str) -> Result<Self> {
107        let path = c_string(path)?;
108        let mut out_resolver = ptr::null_mut();
109        let mut out_error = ptr::null_mut();
110        // SAFETY: The unsafe operation is valid in this context.
111        let status = unsafe {
112            ffi::mdl_bundle_asset_resolver_new(path.as_ptr(), &mut out_resolver, &mut out_error)
113        };
114        crate::util::status_result(status, out_error)?;
115        Ok(Self::from_handle(required_handle(
116            out_resolver,
117            "MDLBundleAssetResolver",
118        )?))
119    }
120
121    #[must_use]
122    /// Calls the corresponding Model I/O method on the wrapped Model I/O bundle asset resolver counterpart.
123    pub fn path(&self) -> Option<String> {
124        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
125        take_string(unsafe { ffi::mdl_bundle_asset_resolver_path(self.handle.as_ptr()) })
126    }
127
128    /// Calls the corresponding Model I/O method on the wrapped Model I/O bundle asset resolver counterpart.
129    pub fn set_path(&self, path: &str) -> Result<()> {
130        let path = c_string(path)?;
131        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
132        unsafe { ffi::mdl_bundle_asset_resolver_set_path(self.handle.as_ptr(), path.as_ptr()) };
133        Ok(())
134    }
135
136    #[must_use]
137    /// Calls the corresponding Model I/O method on the wrapped Model I/O bundle asset resolver counterpart.
138    pub fn as_asset_resolver(&self) -> AssetResolver {
139        AssetResolver::from_handle(self.handle.clone())
140    }
141}
142
143#[derive(Debug, Clone)]
144/// Wraps the corresponding Model I/O relative asset resolver counterpart.
145pub struct RelativeAssetResolver {
146    handle: ObjectHandle,
147}
148
149impl RelativeAssetResolver {
150    /// Builds this wrapper from the retained handle of the wrapped Model I/O relative asset resolver counterpart.
151    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
152        Self { handle }
153    }
154
155    /// Wraps the corresponding Model I/O initializer for the wrapped Model I/O relative asset resolver counterpart.
156    pub fn new(asset: &Asset) -> Result<Self> {
157        let mut out_resolver = ptr::null_mut();
158        let mut out_error = ptr::null_mut();
159        // SAFETY: The unsafe operation is valid in this context.
160        let status = unsafe {
161            ffi::mdl_relative_asset_resolver_new(asset.as_ptr(), &mut out_resolver, &mut out_error)
162        };
163        crate::util::status_result(status, out_error)?;
164        Ok(Self::from_handle(required_handle(
165            out_resolver,
166            "MDLRelativeAssetResolver",
167        )?))
168    }
169
170    #[must_use]
171    /// Calls the corresponding Model I/O method on the wrapped Model I/O relative asset resolver counterpart.
172    pub fn asset(&self) -> Option<Asset> {
173        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
174        let ptr = unsafe { ffi::mdl_relative_asset_resolver_asset(self.handle.as_ptr()) };
175        // SAFETY: The unsafe operation is valid in this context.
176        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(Asset::from_handle)
177    }
178
179    /// Calls the corresponding Model I/O method on the wrapped Model I/O relative asset resolver counterpart.
180    pub fn set_asset(&self, asset: Option<&Asset>) {
181        // SAFETY: The unsafe operation is valid in this context.
182        unsafe {
183            ffi::mdl_relative_asset_resolver_set_asset(
184                self.handle.as_ptr(),
185                asset.map_or(ptr::null_mut(), Asset::as_ptr),
186            );
187        }
188    }
189
190    #[must_use]
191    /// Calls the corresponding Model I/O method on the wrapped Model I/O relative asset resolver counterpart.
192    pub fn as_asset_resolver(&self) -> AssetResolver {
193        AssetResolver::from_handle(self.handle.clone())
194    }
195}