//! System-related parameters

pub use abi::system::*;
use abi::{
    error::Error,
    option::{OptionValue, RequestValue},
};

/// Helper macro for [get_system_info]
pub macro get_system_info($variant_ty:ty) {{
    let mut buffer = [0; <$variant_ty as $crate::io::OptionSizeHint>::SIZE_HINT];
    $crate::system::get_system_info::<$variant_ty>(&mut buffer)
}}

/// Retrieves a system information object
pub fn get_system_info<'de, T: OptionValue<'de>>(buffer: &'de mut [u8]) -> Result<T::Value, Error> {
    let len = unsafe { crate::sys::get_system_info(T::VARIANT.into(), buffer) }?;
    T::load(&buffer[..len])
}

/// Performs an operation on the system, like power management, reset etc
pub fn system_control<'de, T: RequestValue<'de>>(
    buffer: &'de mut [u8],
    request: &T::Request,
) -> Result<T::Response, Error> {
    let len = T::store_request(request, buffer)?;
    let len = unsafe { crate::sys::system_control(T::VARIANT.into(), buffer, len) }?;
    T::load_response(&buffer[..len])
}
