maa-framework 0.5.0

Rust bindings for MaaFramework
Documentation
use std::{fmt::Display, ops::Deref, ptr::null_mut};

use crate::{
    buffer::string_buffer::MaaStringBuffer, internal, maa_bool, CallbackHandler, MaaResult,
    MaaStatus,
};

pub use internal::MaaResId;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub enum MaaResOption {
    Invalid,
}

impl MaaResOption {
    fn get_inner_key(&self) -> internal::MaaResOption {
        match self {
            MaaResOption::Invalid => internal::MaaResOptionEnum_MaaResOption_Invalid,
        }
    }
}

impl Display for MaaResOption {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            MaaResOption::Invalid => write!(f, "Invalid"),
        }
    }
}

/// A resource instance
///
/// # Note
///
/// See [MaaInstance](crate::instance::MaaInstance) for lifetime hints.
#[derive(Debug)]
pub struct MaaResourceInstance<T> {
    pub(crate) handle: internal::MaaResourceHandle,
    _phantom: std::marker::PhantomData<T>,
}

impl<T> Deref for MaaResourceInstance<T> {
    type Target = internal::MaaResourceHandle;

    fn deref(&self) -> &Self::Target {
        &self.handle
    }
}

unsafe impl<T> Send for MaaResourceInstance<T> {}
unsafe impl<T> Sync for MaaResourceInstance<T> {}

impl<T> MaaResourceInstance<T> {
    pub fn new(handler: Option<T>) -> Self
    where
        T: CallbackHandler,
    {
        let handle = unsafe {
            match handler {
                Some(handler) => {
                    let handler = Box::new(handler);
                    let handler = Box::into_raw(handler);
                    internal::MaaResourceCreate(
                        Some(internal::callback_handler::<T>),
                        handler.cast(),
                    )
                }
                None => internal::MaaResourceCreate(None, null_mut()),
            }
        };

        MaaResourceInstance {
            handle,
            _phantom: std::marker::PhantomData,
        }
    }

    pub(crate) fn new_from_handle(handle: internal::MaaResourceHandle) -> Self {
        MaaResourceInstance {
            handle,
            _phantom: std::marker::PhantomData,
        }
    }

    pub fn post_path(&self, path: &str) -> MaaResId {
        let path = internal::to_cstring(path);
        unsafe { internal::MaaResourcePostPath(self.handle, path) }
    }

    pub fn status(&self, id: MaaResId) -> MaaResult<MaaStatus> {
        let status = unsafe { internal::MaaResourceStatus(self.handle, id) };

        MaaStatus::try_from(status)
    }

    pub fn wait(&self, id: MaaResId) -> MaaResult<MaaStatus> {
        let status = unsafe { internal::MaaResourceWait(self.handle, id) };

        MaaStatus::try_from(status)
    }

    pub fn loaded(&self) -> bool {
        let loaded = unsafe { internal::MaaResourceLoaded(self.handle) };
        maa_bool!(loaded)
    }

    pub fn set_option(&self, option: MaaResOption) -> MaaResult<()> {
        let key = option.get_inner_key();
        let ret = unsafe {
            match option {
                MaaResOption::Invalid => {
                    internal::MaaResourceSetOption(self.handle, key, null_mut(), 0)
                }
            }
        };

        if maa_bool!(ret) {
            Ok(())
        } else {
            Err(crate::error::Error::MaaResourceSetOptionError(option))
        }
    }

    pub fn get_hash(&self) -> MaaResult<String> {
        let buffer = MaaStringBuffer::new();

        let ret = unsafe { internal::MaaResourceGetHash(self.handle, buffer.handle) };

        if maa_bool!(ret) {
            Ok(buffer.string())
        } else {
            Err(crate::error::Error::MaaResourceGetHashError)
        }
    }

    pub fn get_task_list(&self) -> MaaResult<String> {
        let buffer = MaaStringBuffer::new();

        let ret = unsafe { internal::MaaResourceGetTaskList(self.handle, buffer.handle) };

        if maa_bool!(ret) {
            let task_list = buffer.string();

            Ok(task_list)
        } else {
            Err(crate::error::Error::MaaResourceGetTaskListError)
        }
    }

    pub fn clear(&self) -> MaaResult<()> {
        let ret = unsafe { internal::MaaResourceClear(self.handle) };

        if maa_bool!(ret) {
            Ok(())
        } else {
            Err(crate::error::Error::MaaResourceClearError)
        }
    }
}

impl<T> Drop for MaaResourceInstance<T> {
    fn drop(&mut self) {
        unsafe {
            internal::MaaResourceDestroy(self.handle);
        }
    }
}