use super::error::{Error, Result};
use super::helpers::{call_buffer, call_buffer_len, call_buffer_str, call_string};
use super::Address;
use crate::panic_or_trap;
use core::num::NonZeroUsize;
use oc_wasm_sys::computer as sys;
use ordered_float::NotNan;
#[must_use = "This function is only useful for its return value"]
pub fn uptime() -> NotNan<f64> {
unsafe { sys::uptime() }
}
#[must_use = "This function is only useful for its return value"]
pub fn cpu_time() -> NotNan<f64> {
unsafe { sys::cpu_time() }
}
#[must_use = "This function is only useful for its return value"]
pub fn world_time() -> u64 {
unsafe { sys::world_time() }
}
#[must_use = "This function is only useful for its return value"]
pub fn address() -> Address {
let mut buffer = uuid::Bytes::default();
unsafe { sys::address(buffer.as_mut_ptr()) };
Address::from_bytes(buffer)
}
#[must_use = "This function is only useful for its return value"]
pub fn tmpfs_address() -> Address {
let mut buffer = uuid::Bytes::default();
unsafe { sys::tmpfs_address(buffer.as_mut_ptr()) };
Address::from_bytes(buffer)
}
#[must_use = "This function is only useful for its return value"]
pub fn installed_ram() -> u32 {
unsafe { sys::installed_ram() }
}
#[must_use = "This function is only useful for its return value"]
pub fn free_ram() -> u32 {
unsafe { sys::free_ram() }
}
pub fn push_signal(signal: &[u8]) -> Result<()> {
Error::from_i32(
unsafe { sys::push_signal(signal.as_ptr()) },
)?;
Ok(())
}
#[must_use = "This function is only useful for its return value"]
pub fn pull_signal_length() -> Option<NonZeroUsize> {
let len =
unsafe{call_buffer_len(sys::pull_signal)};
let len = len.unwrap_or_else(|_| panic_or_trap!("unreachable"));
NonZeroUsize::new(len)
}
pub fn pull_signal(buffer: &mut [u8]) -> Result<Option<&mut [u8]>> {
let ret = unsafe { call_buffer(sys::pull_signal, buffer) }?;
Ok(if ret.is_empty() { None } else { Some(ret) })
}
pub fn acl_start() {
unsafe { sys::acl_start() }
}
#[must_use = "This function is only useful for its return value"]
pub fn acl_next_len() -> Option<NonZeroUsize> {
let len =
unsafe{call_buffer_len(sys::acl_next)};
let len = len.unwrap_or_else(|_| panic_or_trap!("unreachable"));
NonZeroUsize::new(len)
}
pub fn acl_next(buffer: &mut [u8]) -> Result<Option<&mut str>> {
let s = unsafe { call_buffer_str(sys::acl_next, buffer) }?;
Ok(if s.is_empty() { None } else { Some(s) })
}
pub fn add_user(name: &str) -> Result<()> {
unsafe { call_string(sys::add_user, Some(name)) }?;
Ok(())
}
pub fn remove_user(name: &str) -> Result<()> {
unsafe { call_string(sys::remove_user, Some(name)) }?;
Ok(())
}
#[must_use = "This function is only useful for its return value"]
pub fn energy() -> NotNan<f64> {
unsafe { sys::energy() }
}
#[must_use = "This function is only useful for its return value"]
pub fn max_energy() -> NotNan<f64> {
unsafe { sys::max_energy() }
}
#[must_use = "This function is only useful for its return value"]
pub fn char_width(ch: char) -> u32 {
let ch = ch as u32;
unsafe { sys::char_width(ch) }
}
pub fn beep(frequency: u16, duration: u16) {
unsafe { sys::beep(frequency.into(), duration.into()) }
}
pub fn beep_pattern(pattern: &str) {
let result =
unsafe{call_string(sys::beep_pattern, Some(pattern))};
result.unwrap_or_else(|_| panic_or_trap!("unreachable"));
}
pub fn shutdown() -> ! {
unsafe { sys::shutdown() }
}
pub fn reboot() -> ! {
unsafe { sys::reboot() }
}
pub fn error(error: &str) -> ! {
unsafe { sys::error(error.as_ptr(), error.len()) }
}
pub fn debug(message: &str) {
let result = unsafe { call_string(sys::debug, Some(message)) };
result.unwrap_or_else(|_| panic_or_trap!("unreachable"));
}