1use std::ffi::CString;
4use std::ptr::NonNull;
5
6use crate::{MaaError, MaaResult, common, sys};
7
8use std::sync::Arc;
16
17struct ResourceInner {
18 handle: NonNull<sys::MaaResource>,
19 owns_handle: bool,
20 custom_actions: std::sync::Mutex<std::collections::HashMap<String, usize>>, custom_recognitions: std::sync::Mutex<std::collections::HashMap<String, usize>>,
22 callbacks: std::sync::Mutex<std::collections::HashMap<sys::MaaSinkId, usize>>,
23 event_sinks: std::sync::Mutex<std::collections::HashMap<sys::MaaSinkId, usize>>,
24}
25
26unsafe impl Send for ResourceInner {}
27unsafe impl Sync for ResourceInner {}
28
29#[derive(Clone)]
30pub struct Resource {
31 inner: Arc<ResourceInner>,
32}
33
34unsafe impl Send for Resource {}
35unsafe impl Sync for Resource {}
36
37impl Resource {
38 pub fn new() -> MaaResult<Self> {
40 let handle = unsafe { sys::MaaResourceCreate() };
41 if let Some(ptr) = NonNull::new(handle) {
42 Ok(Self {
43 inner: Arc::new(ResourceInner {
44 handle: ptr,
45 owns_handle: true,
46 custom_actions: std::sync::Mutex::new(std::collections::HashMap::new()),
47 custom_recognitions: std::sync::Mutex::new(std::collections::HashMap::new()),
48 callbacks: std::sync::Mutex::new(std::collections::HashMap::new()),
49 event_sinks: std::sync::Mutex::new(std::collections::HashMap::new()),
50 }),
51 })
52 } else {
53 Err(MaaError::NullPointer)
54 }
55 }
56
57 pub unsafe fn from_raw(ptr: *mut sys::MaaResource) -> MaaResult<Self> {
63 if let Some(handle) = NonNull::new(ptr) {
64 Ok(Self {
65 inner: Arc::new(ResourceInner {
66 handle,
67 owns_handle: true,
68 custom_actions: std::sync::Mutex::new(std::collections::HashMap::new()),
69 custom_recognitions: std::sync::Mutex::new(std::collections::HashMap::new()),
70 callbacks: std::sync::Mutex::new(std::collections::HashMap::new()),
71 event_sinks: std::sync::Mutex::new(std::collections::HashMap::new()),
72 }),
73 })
74 } else {
75 Err(MaaError::NullPointer)
76 }
77 }
78
79 pub fn post_bundle(&self, path: &str) -> MaaResult<crate::job::ResJob> {
83 let c_path = CString::new(path)?;
84 let id = unsafe { sys::MaaResourcePostBundle(self.inner.handle.as_ptr(), c_path.as_ptr()) };
85 Ok(crate::job::Job::for_resource(self, id))
86 }
87
88 pub fn loaded(&self) -> bool {
90 unsafe { sys::MaaResourceLoaded(self.inner.handle.as_ptr()) != 0 }
91 }
92
93 pub fn clear(&self) -> MaaResult<()> {
95 let ret = unsafe { sys::MaaResourceClear(self.inner.handle.as_ptr()) };
96 common::check_bool(ret)
97 }
98
99 pub fn status(&self, id: common::MaaId) -> common::MaaStatus {
101 let status = unsafe { sys::MaaResourceStatus(self.inner.handle.as_ptr(), id) };
102 common::MaaStatus(status)
103 }
104
105 pub fn wait(&self, id: common::MaaId) -> common::MaaStatus {
107 let status = unsafe { sys::MaaResourceWait(self.inner.handle.as_ptr(), id) };
108 common::MaaStatus(status)
109 }
110
111 pub fn raw(&self) -> *mut sys::MaaResource {
113 self.inner.handle.as_ptr()
114 }
115
116 pub fn post_ocr_model(&self, path: &str) -> MaaResult<crate::job::ResJob> {
120 let c_path = CString::new(path)?;
121 let id =
122 unsafe { sys::MaaResourcePostOcrModel(self.inner.handle.as_ptr(), c_path.as_ptr()) };
123 Ok(crate::job::Job::for_resource(self, id))
124 }
125
126 pub fn post_pipeline(&self, path: &str) -> MaaResult<crate::job::ResJob> {
128 let c_path = CString::new(path)?;
129 let id =
130 unsafe { sys::MaaResourcePostPipeline(self.inner.handle.as_ptr(), c_path.as_ptr()) };
131 Ok(crate::job::Job::for_resource(self, id))
132 }
133
134 pub fn post_image(&self, path: &str) -> MaaResult<crate::job::ResJob> {
136 let c_path = CString::new(path)?;
137 let id = unsafe { sys::MaaResourcePostImage(self.inner.handle.as_ptr(), c_path.as_ptr()) };
138 Ok(crate::job::Job::for_resource(self, id))
139 }
140
141 pub fn override_pipeline(&self, pipeline_override: &str) -> MaaResult<()> {
145 let c_json = CString::new(pipeline_override)?;
146 let ret = unsafe {
147 sys::MaaResourceOverridePipeline(self.inner.handle.as_ptr(), c_json.as_ptr())
148 };
149 common::check_bool(ret)
150 }
151
152 pub fn override_pipeline_json(&self, pipeline_override: &serde_json::Value) -> MaaResult<()> {
164 self.override_pipeline(&pipeline_override.to_string())
165 }
166
167 pub fn override_next(&self, node_name: &str, next_list: &[&str]) -> MaaResult<()> {
173 let c_name = CString::new(node_name)?;
174 let list_buf = crate::buffer::MaaStringListBuffer::new()?;
175 for item in next_list {
176 list_buf.append(item)?;
177 }
178 let ret = unsafe {
179 sys::MaaResourceOverrideNext(
180 self.inner.handle.as_ptr(),
181 c_name.as_ptr(),
182 list_buf.raw(),
183 )
184 };
185 common::check_bool(ret)
186 }
187
188 pub fn get_node_data(&self, node_name: &str) -> MaaResult<Option<String>> {
190 let c_name = CString::new(node_name)?;
191 let buffer = crate::buffer::MaaStringBuffer::new()?;
192 let ret = unsafe {
193 sys::MaaResourceGetNodeData(self.inner.handle.as_ptr(), c_name.as_ptr(), buffer.raw())
194 };
195 if ret != 0 {
196 Ok(Some(buffer.to_string()))
197 } else {
198 Ok(None)
199 }
200 }
201
202 pub fn get_node_object(
204 &self,
205 node_name: &str,
206 ) -> MaaResult<Option<crate::pipeline::PipelineData>> {
207 if let Some(json_str) = self.get_node_data(node_name)? {
208 let data: crate::pipeline::PipelineData =
209 serde_json::from_str(&json_str).map_err(|e| {
210 MaaError::InvalidConfig(format!("Failed to parse pipeline data: {}", e))
211 })?;
212 Ok(Some(data))
213 } else {
214 Ok(None)
215 }
216 }
217
218 pub fn node_list(&self) -> MaaResult<Vec<String>> {
220 let buffer = crate::buffer::MaaStringListBuffer::new()?;
221 let ret = unsafe { sys::MaaResourceGetNodeList(self.inner.handle.as_ptr(), buffer.raw()) };
222 if ret != 0 {
223 Ok(buffer.to_vec())
224 } else {
225 Err(MaaError::FrameworkError(0))
226 }
227 }
228
229 pub fn hash(&self) -> MaaResult<String> {
231 let buffer = crate::buffer::MaaStringBuffer::new()?;
232 let ret = unsafe { sys::MaaResourceGetHash(self.inner.handle.as_ptr(), buffer.raw()) };
233 if ret != 0 {
234 Ok(buffer.to_string())
235 } else {
236 Err(MaaError::FrameworkError(0))
237 }
238 }
239
240 pub fn get_default_recognition_param(
245 &self,
246 reco_type: &str,
247 ) -> MaaResult<Option<serde_json::Value>> {
248 let c_type = CString::new(reco_type)?;
249 let buffer = crate::buffer::MaaStringBuffer::new()?;
250 let ret = unsafe {
251 sys::MaaResourceGetDefaultRecognitionParam(
252 self.inner.handle.as_ptr(),
253 c_type.as_ptr(),
254 buffer.raw(),
255 )
256 };
257 if ret != 0 {
258 let json_str = buffer.to_string();
259 let val: serde_json::Value = serde_json::from_str(&json_str).map_err(|e| {
260 MaaError::InvalidConfig(format!("Failed to parse default params: {}", e))
261 })?;
262 Ok(Some(val))
263 } else {
264 Ok(None)
265 }
266 }
267
268 pub fn get_default_action_param(
273 &self,
274 action_type: &str,
275 ) -> MaaResult<Option<serde_json::Value>> {
276 let c_type = CString::new(action_type)?;
277 let buffer = crate::buffer::MaaStringBuffer::new()?;
278 let ret = unsafe {
279 sys::MaaResourceGetDefaultActionParam(
280 self.inner.handle.as_ptr(),
281 c_type.as_ptr(),
282 buffer.raw(),
283 )
284 };
285 if ret != 0 {
286 let json_str = buffer.to_string();
287 let val: serde_json::Value = serde_json::from_str(&json_str).map_err(|e| {
288 MaaError::InvalidConfig(format!("Failed to parse default params: {}", e))
289 })?;
290 Ok(Some(val))
291 } else {
292 Ok(None)
293 }
294 }
295
296 pub fn use_cpu(&self) -> MaaResult<()> {
300 let mut ep: i32 =
301 sys::MaaInferenceExecutionProviderEnum_MaaInferenceExecutionProvider_CPU as i32;
302 let ret1 = unsafe {
303 sys::MaaResourceSetOption(
304 self.inner.handle.as_ptr(),
305 sys::MaaResOptionEnum_MaaResOption_InferenceExecutionProvider as i32,
306 &mut ep as *mut _ as *mut std::ffi::c_void,
307 std::mem::size_of::<i32>() as u64,
308 )
309 };
310 common::check_bool(ret1)?;
311
312 let mut device: i32 = sys::MaaInferenceDeviceEnum_MaaInferenceDevice_CPU as i32;
313 let ret2 = unsafe {
314 sys::MaaResourceSetOption(
315 self.inner.handle.as_ptr(),
316 sys::MaaResOptionEnum_MaaResOption_InferenceDevice as i32,
317 &mut device as *mut _ as *mut std::ffi::c_void,
318 std::mem::size_of::<i32>() as u64,
319 )
320 };
321 common::check_bool(ret2)
322 }
323
324 pub fn use_directml(&self, device_id: i32) -> MaaResult<()> {
329 let mut ep: i32 =
330 sys::MaaInferenceExecutionProviderEnum_MaaInferenceExecutionProvider_DirectML as i32;
331 let ret1 = unsafe {
332 sys::MaaResourceSetOption(
333 self.inner.handle.as_ptr(),
334 sys::MaaResOptionEnum_MaaResOption_InferenceExecutionProvider as i32,
335 &mut ep as *mut _ as *mut std::ffi::c_void,
336 std::mem::size_of::<i32>() as u64,
337 )
338 };
339 common::check_bool(ret1)?;
340
341 let mut device = device_id;
342 let ret2 = unsafe {
343 sys::MaaResourceSetOption(
344 self.inner.handle.as_ptr(),
345 sys::MaaResOptionEnum_MaaResOption_InferenceDevice as i32,
346 &mut device as *mut _ as *mut std::ffi::c_void,
347 std::mem::size_of::<i32>() as u64,
348 )
349 };
350 common::check_bool(ret2)
351 }
352
353 pub fn use_webgpu(&self, device_id: i32) -> MaaResult<()> {
358 let mut ep: i32 =
359 sys::MaaInferenceExecutionProviderEnum_MaaInferenceExecutionProvider_WebGPU as i32;
360 let ret1 = unsafe {
361 sys::MaaResourceSetOption(
362 self.inner.handle.as_ptr(),
363 sys::MaaResOptionEnum_MaaResOption_InferenceExecutionProvider as i32,
364 &mut ep as *mut _ as *mut std::ffi::c_void,
365 std::mem::size_of::<i32>() as u64,
366 )
367 };
368 common::check_bool(ret1)?;
369
370 let mut device = device_id;
371 let ret2 = unsafe {
372 sys::MaaResourceSetOption(
373 self.inner.handle.as_ptr(),
374 sys::MaaResOptionEnum_MaaResOption_InferenceDevice as i32,
375 &mut device as *mut _ as *mut std::ffi::c_void,
376 std::mem::size_of::<i32>() as u64,
377 )
378 };
379 common::check_bool(ret2)
380 }
381
382 pub fn add_sink<F>(&self, callback: F) -> MaaResult<sys::MaaSinkId>
388 where
389 F: Fn(&str, &str) + Send + Sync + 'static,
390 {
391 let (cb_fn, cb_arg) = crate::callback::EventCallback::new(callback);
392 let sink_id = unsafe { sys::MaaResourceAddSink(self.inner.handle.as_ptr(), cb_fn, cb_arg) };
393 if sink_id != 0 {
394 self.inner
395 .callbacks
396 .lock()
397 .unwrap()
398 .insert(sink_id, cb_arg as usize);
399 Ok(sink_id)
400 } else {
401 unsafe { crate::callback::EventCallback::drop_callback(cb_arg) };
402 Err(MaaError::FrameworkError(0))
403 }
404 }
405
406 pub fn add_event_sink(
418 &self,
419 sink: Box<dyn crate::event_sink::EventSink>,
420 ) -> MaaResult<sys::MaaSinkId> {
421 let handle_id = self.inner.handle.as_ptr() as crate::common::MaaId;
422 let (cb, arg) = crate::callback::EventCallback::new_sink(handle_id, sink);
423 let id = unsafe { sys::MaaResourceAddSink(self.inner.handle.as_ptr(), cb, arg) };
424 if id > 0 {
425 self.inner
426 .event_sinks
427 .lock()
428 .unwrap()
429 .insert(id, arg as usize);
430 Ok(id)
431 } else {
432 unsafe { crate::callback::EventCallback::drop_sink(arg) };
433 Err(MaaError::FrameworkError(0))
434 }
435 }
436
437 pub fn remove_sink(&self, sink_id: sys::MaaSinkId) {
439 unsafe { sys::MaaResourceRemoveSink(self.inner.handle.as_ptr(), sink_id) }
440 if let Some(ptr) = self.inner.callbacks.lock().unwrap().remove(&sink_id) {
441 unsafe { crate::callback::EventCallback::drop_callback(ptr as *mut std::ffi::c_void) };
442 } else if let Some(ptr) = self.inner.event_sinks.lock().unwrap().remove(&sink_id) {
443 unsafe { crate::callback::EventCallback::drop_sink(ptr as *mut std::ffi::c_void) };
444 }
445 }
446
447 pub fn clear_sinks(&self) {
449 unsafe { sys::MaaResourceClearSinks(self.inner.handle.as_ptr()) }
450 let mut callbacks = self.inner.callbacks.lock().unwrap();
451 for (_, ptr) in callbacks.drain() {
452 unsafe { crate::callback::EventCallback::drop_callback(ptr as *mut std::ffi::c_void) };
453 }
454 let mut event_sinks = self.inner.event_sinks.lock().unwrap();
455 for (_, ptr) in event_sinks.drain() {
456 unsafe { crate::callback::EventCallback::drop_sink(ptr as *mut std::ffi::c_void) };
457 }
458 }
459
460 pub fn override_image(
468 &self,
469 image_name: &str,
470 image: &crate::buffer::MaaImageBuffer,
471 ) -> MaaResult<()> {
472 let c_name = CString::new(image_name)?;
473 let ret = unsafe {
474 sys::MaaResourceOverrideImage(self.inner.handle.as_ptr(), c_name.as_ptr(), image.raw())
475 };
476 common::check_bool(ret)
477 }
478
479 pub fn use_auto_ep(&self) -> MaaResult<()> {
485 let mut ep: i32 =
486 sys::MaaInferenceExecutionProviderEnum_MaaInferenceExecutionProvider_Auto as i32;
487 let ret1 = unsafe {
488 sys::MaaResourceSetOption(
489 self.inner.handle.as_ptr(),
490 sys::MaaResOptionEnum_MaaResOption_InferenceExecutionProvider as i32,
491 &mut ep as *mut _ as *mut std::ffi::c_void,
492 std::mem::size_of::<i32>() as u64,
493 )
494 };
495 common::check_bool(ret1)?;
496
497 let mut device: i32 = sys::MaaInferenceDeviceEnum_MaaInferenceDevice_Auto as i32;
498 let ret2 = unsafe {
499 sys::MaaResourceSetOption(
500 self.inner.handle.as_ptr(),
501 sys::MaaResOptionEnum_MaaResOption_InferenceDevice as i32,
502 &mut device as *mut _ as *mut std::ffi::c_void,
503 std::mem::size_of::<i32>() as u64,
504 )
505 };
506 common::check_bool(ret2)
507 }
508
509 #[deprecated(note = "MaaDeps no longer ships CoreML; use `use_webgpu` instead")]
516 pub fn use_coreml(&self, coreml_flag: i32) -> MaaResult<()> {
517 let mut ep: i32 =
518 sys::MaaInferenceExecutionProviderEnum_MaaInferenceExecutionProvider_CoreML as i32;
519 let ret1 = unsafe {
520 sys::MaaResourceSetOption(
521 self.inner.handle.as_ptr(),
522 sys::MaaResOptionEnum_MaaResOption_InferenceExecutionProvider as i32,
523 &mut ep as *mut _ as *mut std::ffi::c_void,
524 std::mem::size_of::<i32>() as u64,
525 )
526 };
527 common::check_bool(ret1)?;
528
529 let mut device = coreml_flag;
530 let ret2 = unsafe {
531 sys::MaaResourceSetOption(
532 self.inner.handle.as_ptr(),
533 sys::MaaResOptionEnum_MaaResOption_InferenceDevice as i32,
534 &mut device as *mut _ as *mut std::ffi::c_void,
535 std::mem::size_of::<i32>() as u64,
536 )
537 };
538 common::check_bool(ret2)
539 }
540
541 pub fn use_cuda(&self, nvidia_gpu_id: i32) -> MaaResult<()> {
546 let mut ep: i32 =
547 sys::MaaInferenceExecutionProviderEnum_MaaInferenceExecutionProvider_CUDA as i32;
548 let ret1 = unsafe {
549 sys::MaaResourceSetOption(
550 self.inner.handle.as_ptr(),
551 sys::MaaResOptionEnum_MaaResOption_InferenceExecutionProvider as i32,
552 &mut ep as *mut _ as *mut std::ffi::c_void,
553 std::mem::size_of::<i32>() as u64,
554 )
555 };
556 common::check_bool(ret1)?;
557
558 let mut device = nvidia_gpu_id;
559 let ret2 = unsafe {
560 sys::MaaResourceSetOption(
561 self.inner.handle.as_ptr(),
562 sys::MaaResOptionEnum_MaaResOption_InferenceDevice as i32,
563 &mut device as *mut _ as *mut std::ffi::c_void,
564 std::mem::size_of::<i32>() as u64,
565 )
566 };
567 common::check_bool(ret2)
568 }
569
570 pub fn unregister_custom_recognition(&self, name: &str) -> MaaResult<()> {
574 let c_name = CString::new(name)?;
575 let ret = unsafe {
576 sys::MaaResourceUnregisterCustomRecognition(self.inner.handle.as_ptr(), c_name.as_ptr())
577 };
578 if ret != 0 {
579 self.inner.custom_recognitions.lock().unwrap().remove(name);
580 }
581 common::check_bool(ret)
582 }
583
584 pub fn unregister_custom_action(&self, name: &str) -> MaaResult<()> {
586 let c_name = CString::new(name)?;
587 let ret = unsafe {
588 sys::MaaResourceUnregisterCustomAction(self.inner.handle.as_ptr(), c_name.as_ptr())
589 };
590 if ret != 0 {
591 self.inner.custom_actions.lock().unwrap().remove(name);
592 }
593 common::check_bool(ret)
594 }
595
596 pub fn custom_recognition_list(&self) -> MaaResult<Vec<String>> {
598 let buffer = crate::buffer::MaaStringListBuffer::new()?;
599 let ret = unsafe {
600 sys::MaaResourceGetCustomRecognitionList(self.inner.handle.as_ptr(), buffer.raw())
601 };
602 if ret != 0 {
603 Ok(buffer.to_vec())
604 } else {
605 Err(MaaError::FrameworkError(0))
606 }
607 }
608
609 pub fn custom_action_list(&self) -> MaaResult<Vec<String>> {
611 let buffer = crate::buffer::MaaStringListBuffer::new()?;
612 let ret = unsafe {
613 sys::MaaResourceGetCustomActionList(self.inner.handle.as_ptr(), buffer.raw())
614 };
615 if ret != 0 {
616 Ok(buffer.to_vec())
617 } else {
618 Err(MaaError::FrameworkError(0))
619 }
620 }
621
622 pub fn clear_custom_recognition(&self) -> MaaResult<()> {
624 let ret = unsafe { sys::MaaResourceClearCustomRecognition(self.inner.handle.as_ptr()) };
625 if ret != 0 {
626 let mut recos = self.inner.custom_recognitions.lock().unwrap();
627 for (_, ptr) in recos.drain() {
628 unsafe {
629 let _ = Box::from_raw(ptr as *mut Box<dyn crate::custom::CustomRecognition>);
630 }
631 }
632 }
633 common::check_bool(ret)
634 }
635
636 pub fn clear_custom_action(&self) -> MaaResult<()> {
638 let ret = unsafe { sys::MaaResourceClearCustomAction(self.inner.handle.as_ptr()) };
639 if ret != 0 {
640 let mut actions = self.inner.custom_actions.lock().unwrap();
641 for (_, ptr) in actions.drain() {
642 unsafe {
643 let _ = Box::from_raw(ptr as *mut Box<dyn crate::custom::CustomAction>);
644 }
645 }
646 }
647 common::check_bool(ret)
648 }
649 pub(crate) fn custom_recognitions(
650 &self,
651 ) -> &std::sync::Mutex<std::collections::HashMap<String, usize>> {
652 &self.inner.custom_recognitions
653 }
654
655 pub(crate) fn custom_actions(
656 &self,
657 ) -> &std::sync::Mutex<std::collections::HashMap<String, usize>> {
658 &self.inner.custom_actions
659 }
660}
661
662impl Drop for ResourceInner {
663 fn drop(&mut self) {
664 unsafe {
665 if self.owns_handle {
666 sys::MaaResourceClearSinks(self.handle.as_ptr());
667 {
668 let mut callbacks = self.callbacks.lock().unwrap();
669 for (_, ptr) in callbacks.drain() {
670 let _ = crate::callback::EventCallback::drop_callback(
671 ptr as *mut std::ffi::c_void,
672 );
673 }
674 }
675 {
676 let mut event_sinks = self.event_sinks.lock().unwrap();
677 for (_, ptr) in event_sinks.drain() {
678 let _ =
679 crate::callback::EventCallback::drop_sink(ptr as *mut std::ffi::c_void);
680 }
681 }
682
683 sys::MaaResourceClearCustomAction(self.handle.as_ptr());
684 sys::MaaResourceClearCustomRecognition(self.handle.as_ptr());
685
686 {
687 let mut actions = self.custom_actions.lock().unwrap();
688 for (_, ptr) in actions.drain() {
689 let _ = Box::from_raw(ptr as *mut Box<dyn crate::custom::CustomAction>);
690 }
691 }
692 {
693 let mut recos = self.custom_recognitions.lock().unwrap();
694 for (_, ptr) in recos.drain() {
695 let _ =
696 Box::from_raw(ptr as *mut Box<dyn crate::custom::CustomRecognition>);
697 }
698 }
699
700 sys::MaaResourceDestroy(self.handle.as_ptr());
701 }
702 }
703 }
704}
705
706pub struct ResourceRef<'a> {
714 handle: *mut sys::MaaResource,
715 _marker: std::marker::PhantomData<&'a ()>,
716}
717
718impl<'a> ResourceRef<'a> {
719 pub(crate) fn from_ptr(handle: *mut sys::MaaResource) -> Option<Self> {
720 if handle.is_null() {
721 None
722 } else {
723 Some(Self {
724 handle,
725 _marker: std::marker::PhantomData,
726 })
727 }
728 }
729
730 pub fn loaded(&self) -> bool {
732 unsafe { sys::MaaResourceLoaded(self.handle) != 0 }
733 }
734
735 pub fn status(&self, id: common::MaaId) -> common::MaaStatus {
737 let status = unsafe { sys::MaaResourceStatus(self.handle, id) };
738 common::MaaStatus(status)
739 }
740
741 pub fn wait(&self, id: common::MaaId) -> common::MaaStatus {
743 let status = unsafe { sys::MaaResourceWait(self.handle, id) };
744 common::MaaStatus(status)
745 }
746
747 pub fn hash(&self) -> MaaResult<String> {
749 let buffer = crate::buffer::MaaStringBuffer::new()?;
750 let ret = unsafe { sys::MaaResourceGetHash(self.handle, buffer.raw()) };
751 if ret != 0 {
752 Ok(buffer.to_string())
753 } else {
754 Err(MaaError::FrameworkError(0))
755 }
756 }
757
758 pub fn get_default_recognition_param(
760 &self,
761 reco_type: &str,
762 ) -> MaaResult<Option<serde_json::Value>> {
763 let c_type = std::ffi::CString::new(reco_type)?;
764 let buffer = crate::buffer::MaaStringBuffer::new()?;
765 let ret = unsafe {
766 sys::MaaResourceGetDefaultRecognitionParam(self.handle, c_type.as_ptr(), buffer.raw())
767 };
768 if ret != 0 {
769 let json_str = buffer.to_string();
770 let val: serde_json::Value = serde_json::from_str(&json_str).map_err(|e| {
771 MaaError::InvalidConfig(format!("Failed to parse default params: {}", e))
772 })?;
773 Ok(Some(val))
774 } else {
775 Ok(None)
776 }
777 }
778
779 pub fn get_default_action_param(
781 &self,
782 action_type: &str,
783 ) -> MaaResult<Option<serde_json::Value>> {
784 let c_type = std::ffi::CString::new(action_type)?;
785 let buffer = crate::buffer::MaaStringBuffer::new()?;
786 let ret = unsafe {
787 sys::MaaResourceGetDefaultActionParam(self.handle, c_type.as_ptr(), buffer.raw())
788 };
789 if ret != 0 {
790 let json_str = buffer.to_string();
791 let val: serde_json::Value = serde_json::from_str(&json_str).map_err(|e| {
792 MaaError::InvalidConfig(format!("Failed to parse default params: {}", e))
793 })?;
794 Ok(Some(val))
795 } else {
796 Ok(None)
797 }
798 }
799
800 pub fn node_list(&self) -> MaaResult<Vec<String>> {
802 let buffer = crate::buffer::MaaStringListBuffer::new()?;
803 let ret = unsafe { sys::MaaResourceGetNodeList(self.handle, buffer.raw()) };
804 if ret != 0 {
805 Ok(buffer.to_vec())
806 } else {
807 Err(MaaError::FrameworkError(0))
808 }
809 }
810
811 pub fn get_node_data(&self, node_name: &str) -> MaaResult<Option<String>> {
813 let c_name = std::ffi::CString::new(node_name)?;
814 let buffer = crate::buffer::MaaStringBuffer::new()?;
815 let ret =
816 unsafe { sys::MaaResourceGetNodeData(self.handle, c_name.as_ptr(), buffer.raw()) };
817 if ret != 0 {
818 Ok(Some(buffer.to_string()))
819 } else {
820 Ok(None)
821 }
822 }
823
824 pub fn raw(&self) -> *mut sys::MaaResource {
826 self.handle
827 }
828}