1use std::ffi::CString;
4use std::ptr::NonNull;
5
6use crate::{common, sys, MaaError, MaaResult};
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 add_sink<F>(&self, callback: F) -> MaaResult<sys::MaaSinkId>
359 where
360 F: Fn(&str, &str) + Send + Sync + 'static,
361 {
362 let (cb_fn, cb_arg) = crate::callback::EventCallback::new(callback);
363 let sink_id = unsafe { sys::MaaResourceAddSink(self.inner.handle.as_ptr(), cb_fn, cb_arg) };
364 if sink_id != 0 {
365 self.inner
366 .callbacks
367 .lock()
368 .unwrap()
369 .insert(sink_id, cb_arg as usize);
370 Ok(sink_id)
371 } else {
372 unsafe { crate::callback::EventCallback::drop_callback(cb_arg) };
373 Err(MaaError::FrameworkError(0))
374 }
375 }
376
377 pub fn add_event_sink(
389 &self,
390 sink: Box<dyn crate::event_sink::EventSink>,
391 ) -> MaaResult<sys::MaaSinkId> {
392 let handle_id = self.inner.handle.as_ptr() as crate::common::MaaId;
393 let (cb, arg) = crate::callback::EventCallback::new_sink(handle_id, sink);
394 let id = unsafe { sys::MaaResourceAddSink(self.inner.handle.as_ptr(), cb, arg) };
395 if id > 0 {
396 self.inner
397 .event_sinks
398 .lock()
399 .unwrap()
400 .insert(id, arg as usize);
401 Ok(id)
402 } else {
403 unsafe { crate::callback::EventCallback::drop_sink(arg) };
404 Err(MaaError::FrameworkError(0))
405 }
406 }
407
408 pub fn remove_sink(&self, sink_id: sys::MaaSinkId) {
410 unsafe { sys::MaaResourceRemoveSink(self.inner.handle.as_ptr(), sink_id) }
411 if let Some(ptr) = self.inner.callbacks.lock().unwrap().remove(&sink_id) {
412 unsafe { crate::callback::EventCallback::drop_callback(ptr as *mut std::ffi::c_void) };
413 } else if let Some(ptr) = self.inner.event_sinks.lock().unwrap().remove(&sink_id) {
414 unsafe { crate::callback::EventCallback::drop_sink(ptr as *mut std::ffi::c_void) };
415 }
416 }
417
418 pub fn clear_sinks(&self) {
420 unsafe { sys::MaaResourceClearSinks(self.inner.handle.as_ptr()) }
421 let mut callbacks = self.inner.callbacks.lock().unwrap();
422 for (_, ptr) in callbacks.drain() {
423 unsafe { crate::callback::EventCallback::drop_callback(ptr as *mut std::ffi::c_void) };
424 }
425 let mut event_sinks = self.inner.event_sinks.lock().unwrap();
426 for (_, ptr) in event_sinks.drain() {
427 unsafe { crate::callback::EventCallback::drop_sink(ptr as *mut std::ffi::c_void) };
428 }
429 }
430
431 pub fn override_image(
439 &self,
440 image_name: &str,
441 image: &crate::buffer::MaaImageBuffer,
442 ) -> MaaResult<()> {
443 let c_name = CString::new(image_name)?;
444 let ret = unsafe {
445 sys::MaaResourceOverrideImage(self.inner.handle.as_ptr(), c_name.as_ptr(), image.raw())
446 };
447 common::check_bool(ret)
448 }
449
450 pub fn use_auto_ep(&self) -> MaaResult<()> {
454 let mut ep: i32 =
455 sys::MaaInferenceExecutionProviderEnum_MaaInferenceExecutionProvider_Auto as i32;
456 let ret1 = unsafe {
457 sys::MaaResourceSetOption(
458 self.inner.handle.as_ptr(),
459 sys::MaaResOptionEnum_MaaResOption_InferenceExecutionProvider as i32,
460 &mut ep as *mut _ as *mut std::ffi::c_void,
461 std::mem::size_of::<i32>() as u64,
462 )
463 };
464 common::check_bool(ret1)?;
465
466 let mut device: i32 = sys::MaaInferenceDeviceEnum_MaaInferenceDevice_Auto as i32;
467 let ret2 = unsafe {
468 sys::MaaResourceSetOption(
469 self.inner.handle.as_ptr(),
470 sys::MaaResOptionEnum_MaaResOption_InferenceDevice as i32,
471 &mut device as *mut _ as *mut std::ffi::c_void,
472 std::mem::size_of::<i32>() as u64,
473 )
474 };
475 common::check_bool(ret2)
476 }
477
478 pub fn use_coreml(&self, coreml_flag: i32) -> MaaResult<()> {
483 let mut ep: i32 =
484 sys::MaaInferenceExecutionProviderEnum_MaaInferenceExecutionProvider_CoreML as i32;
485 let ret1 = unsafe {
486 sys::MaaResourceSetOption(
487 self.inner.handle.as_ptr(),
488 sys::MaaResOptionEnum_MaaResOption_InferenceExecutionProvider as i32,
489 &mut ep as *mut _ as *mut std::ffi::c_void,
490 std::mem::size_of::<i32>() as u64,
491 )
492 };
493 common::check_bool(ret1)?;
494
495 let mut device = coreml_flag;
496 let ret2 = unsafe {
497 sys::MaaResourceSetOption(
498 self.inner.handle.as_ptr(),
499 sys::MaaResOptionEnum_MaaResOption_InferenceDevice as i32,
500 &mut device as *mut _ as *mut std::ffi::c_void,
501 std::mem::size_of::<i32>() as u64,
502 )
503 };
504 common::check_bool(ret2)
505 }
506
507 pub fn use_cuda(&self, nvidia_gpu_id: i32) -> MaaResult<()> {
512 let mut ep: i32 =
513 sys::MaaInferenceExecutionProviderEnum_MaaInferenceExecutionProvider_CUDA as i32;
514 let ret1 = unsafe {
515 sys::MaaResourceSetOption(
516 self.inner.handle.as_ptr(),
517 sys::MaaResOptionEnum_MaaResOption_InferenceExecutionProvider as i32,
518 &mut ep as *mut _ as *mut std::ffi::c_void,
519 std::mem::size_of::<i32>() as u64,
520 )
521 };
522 common::check_bool(ret1)?;
523
524 let mut device = nvidia_gpu_id;
525 let ret2 = unsafe {
526 sys::MaaResourceSetOption(
527 self.inner.handle.as_ptr(),
528 sys::MaaResOptionEnum_MaaResOption_InferenceDevice as i32,
529 &mut device as *mut _ as *mut std::ffi::c_void,
530 std::mem::size_of::<i32>() as u64,
531 )
532 };
533 common::check_bool(ret2)
534 }
535
536 pub fn unregister_custom_recognition(&self, name: &str) -> MaaResult<()> {
540 let c_name = CString::new(name)?;
541 let ret = unsafe {
542 sys::MaaResourceUnregisterCustomRecognition(self.inner.handle.as_ptr(), c_name.as_ptr())
543 };
544 if ret != 0 {
545 self.inner.custom_recognitions.lock().unwrap().remove(name);
546 }
547 common::check_bool(ret)
548 }
549
550 pub fn unregister_custom_action(&self, name: &str) -> MaaResult<()> {
552 let c_name = CString::new(name)?;
553 let ret = unsafe {
554 sys::MaaResourceUnregisterCustomAction(self.inner.handle.as_ptr(), c_name.as_ptr())
555 };
556 if ret != 0 {
557 self.inner.custom_actions.lock().unwrap().remove(name);
558 }
559 common::check_bool(ret)
560 }
561
562 pub fn custom_recognition_list(&self) -> MaaResult<Vec<String>> {
564 let buffer = crate::buffer::MaaStringListBuffer::new()?;
565 let ret = unsafe {
566 sys::MaaResourceGetCustomRecognitionList(self.inner.handle.as_ptr(), buffer.raw())
567 };
568 if ret != 0 {
569 Ok(buffer.to_vec())
570 } else {
571 Err(MaaError::FrameworkError(0))
572 }
573 }
574
575 pub fn custom_action_list(&self) -> MaaResult<Vec<String>> {
577 let buffer = crate::buffer::MaaStringListBuffer::new()?;
578 let ret = unsafe {
579 sys::MaaResourceGetCustomActionList(self.inner.handle.as_ptr(), buffer.raw())
580 };
581 if ret != 0 {
582 Ok(buffer.to_vec())
583 } else {
584 Err(MaaError::FrameworkError(0))
585 }
586 }
587
588 pub fn clear_custom_recognition(&self) -> MaaResult<()> {
590 let ret = unsafe { sys::MaaResourceClearCustomRecognition(self.inner.handle.as_ptr()) };
591 if ret != 0 {
592 let mut recos = self.inner.custom_recognitions.lock().unwrap();
593 for (_, ptr) in recos.drain() {
594 unsafe {
595 let _ = Box::from_raw(ptr as *mut Box<dyn crate::custom::CustomRecognition>);
596 }
597 }
598 }
599 common::check_bool(ret)
600 }
601
602 pub fn clear_custom_action(&self) -> MaaResult<()> {
604 let ret = unsafe { sys::MaaResourceClearCustomAction(self.inner.handle.as_ptr()) };
605 if ret != 0 {
606 let mut actions = self.inner.custom_actions.lock().unwrap();
607 for (_, ptr) in actions.drain() {
608 unsafe {
609 let _ = Box::from_raw(ptr as *mut Box<dyn crate::custom::CustomAction>);
610 }
611 }
612 }
613 common::check_bool(ret)
614 }
615 pub(crate) fn custom_recognitions(
616 &self,
617 ) -> &std::sync::Mutex<std::collections::HashMap<String, usize>> {
618 &self.inner.custom_recognitions
619 }
620
621 pub(crate) fn custom_actions(
622 &self,
623 ) -> &std::sync::Mutex<std::collections::HashMap<String, usize>> {
624 &self.inner.custom_actions
625 }
626}
627
628impl Drop for ResourceInner {
629 fn drop(&mut self) {
630 unsafe {
631 {
632 let mut callbacks = self.callbacks.lock().unwrap();
633 for (_, ptr) in callbacks.drain() {
634 let _ =
635 crate::callback::EventCallback::drop_callback(ptr as *mut std::ffi::c_void);
636 }
637 }
638 {
639 let mut event_sinks = self.event_sinks.lock().unwrap();
640 for (_, ptr) in event_sinks.drain() {
641 let _ = crate::callback::EventCallback::drop_sink(ptr as *mut std::ffi::c_void);
642 }
643 }
644 sys::MaaResourceClearSinks(self.handle.as_ptr());
645 sys::MaaResourceClearCustomAction(self.handle.as_ptr());
646 sys::MaaResourceClearCustomRecognition(self.handle.as_ptr());
647
648 {
649 let mut actions = self.custom_actions.lock().unwrap();
650 for (_, ptr) in actions.drain() {
651 let _ = Box::from_raw(ptr as *mut Box<dyn crate::custom::CustomAction>);
652 }
653 }
654 {
655 let mut recos = self.custom_recognitions.lock().unwrap();
656 for (_, ptr) in recos.drain() {
657 let _ = Box::from_raw(ptr as *mut Box<dyn crate::custom::CustomRecognition>);
658 }
659 }
660
661 if self.owns_handle {
662 sys::MaaResourceDestroy(self.handle.as_ptr())
663 }
664 }
665 }
666}
667
668pub struct ResourceRef<'a> {
676 handle: *mut sys::MaaResource,
677 _marker: std::marker::PhantomData<&'a ()>,
678}
679
680impl<'a> ResourceRef<'a> {
681 pub(crate) fn from_ptr(handle: *mut sys::MaaResource) -> Option<Self> {
682 if handle.is_null() {
683 None
684 } else {
685 Some(Self {
686 handle,
687 _marker: std::marker::PhantomData,
688 })
689 }
690 }
691
692 pub fn loaded(&self) -> bool {
694 unsafe { sys::MaaResourceLoaded(self.handle) != 0 }
695 }
696
697 pub fn status(&self, id: common::MaaId) -> common::MaaStatus {
699 let status = unsafe { sys::MaaResourceStatus(self.handle, id) };
700 common::MaaStatus(status)
701 }
702
703 pub fn wait(&self, id: common::MaaId) -> common::MaaStatus {
705 let status = unsafe { sys::MaaResourceWait(self.handle, id) };
706 common::MaaStatus(status)
707 }
708
709 pub fn hash(&self) -> MaaResult<String> {
711 let buffer = crate::buffer::MaaStringBuffer::new()?;
712 let ret = unsafe { sys::MaaResourceGetHash(self.handle, buffer.raw()) };
713 if ret != 0 {
714 Ok(buffer.to_string())
715 } else {
716 Err(MaaError::FrameworkError(0))
717 }
718 }
719
720 pub fn get_default_recognition_param(
722 &self,
723 reco_type: &str,
724 ) -> MaaResult<Option<serde_json::Value>> {
725 let c_type = std::ffi::CString::new(reco_type)?;
726 let buffer = crate::buffer::MaaStringBuffer::new()?;
727 let ret = unsafe {
728 sys::MaaResourceGetDefaultRecognitionParam(self.handle, c_type.as_ptr(), buffer.raw())
729 };
730 if ret != 0 {
731 let json_str = buffer.to_string();
732 let val: serde_json::Value = serde_json::from_str(&json_str).map_err(|e| {
733 MaaError::InvalidConfig(format!("Failed to parse default params: {}", e))
734 })?;
735 Ok(Some(val))
736 } else {
737 Ok(None)
738 }
739 }
740
741 pub fn get_default_action_param(
743 &self,
744 action_type: &str,
745 ) -> MaaResult<Option<serde_json::Value>> {
746 let c_type = std::ffi::CString::new(action_type)?;
747 let buffer = crate::buffer::MaaStringBuffer::new()?;
748 let ret = unsafe {
749 sys::MaaResourceGetDefaultActionParam(self.handle, c_type.as_ptr(), buffer.raw())
750 };
751 if ret != 0 {
752 let json_str = buffer.to_string();
753 let val: serde_json::Value = serde_json::from_str(&json_str).map_err(|e| {
754 MaaError::InvalidConfig(format!("Failed to parse default params: {}", e))
755 })?;
756 Ok(Some(val))
757 } else {
758 Ok(None)
759 }
760 }
761
762 pub fn node_list(&self) -> MaaResult<Vec<String>> {
764 let buffer = crate::buffer::MaaStringListBuffer::new()?;
765 let ret = unsafe { sys::MaaResourceGetNodeList(self.handle, buffer.raw()) };
766 if ret != 0 {
767 Ok(buffer.to_vec())
768 } else {
769 Err(MaaError::FrameworkError(0))
770 }
771 }
772
773 pub fn get_node_data(&self, node_name: &str) -> MaaResult<Option<String>> {
775 let c_name = std::ffi::CString::new(node_name)?;
776 let buffer = crate::buffer::MaaStringBuffer::new()?;
777 let ret =
778 unsafe { sys::MaaResourceGetNodeData(self.handle, c_name.as_ptr(), buffer.raw()) };
779 if ret != 0 {
780 Ok(Some(buffer.to_string()))
781 } else {
782 Ok(None)
783 }
784 }
785
786 pub fn raw(&self) -> *mut sys::MaaResource {
788 self.handle
789 }
790}