#[allow(unused_imports)] use crate::{
c_api::{NCRESULT_ERR, NCRESULT_OK},
Nc, NcDirect, NcError, NcPlane, NcResult, NcVisual, NcVisualOptions,
};
#[macro_export]
macro_rules! sleep {
($s:expr) => {
std::thread::sleep(std::time::Duration::from_secs($s));
};
($s:expr, $ms:expr) => {
std::thread::sleep(std::time::Duration::from_millis($s * 1000 + $ms));
};
($s:expr, $ms:expr, $us:expr) => {
std::thread::sleep(std::time::Duration::from_micros(
$s * 1_000_000 + $ms * 1_000 + $us,
));
};
($s:expr, $ms:expr, $us:expr, $ns:expr) => {
std::thread::sleep(std::time::Duration::from_nanos(
$s * 1_000_000_000 + $ms * 1_000_000 + $us * 1_000 + $ns,
));
};
}
#[macro_export]
macro_rules! nc_render_sleep {
($nc:expr, $( $sleep_args:expr),+ ) => {
$crate::Nc::render($nc)?;
sleep![$( $sleep_args ),+];
};
($nc:expr, $( $sleep_args:expr),+ ,) => {
rsleep![$nc, $( $sleep_args ),* ]
};
}
#[macro_export]
macro_rules! pile_render_sleep {
($p:expr, $( $sleep_args:expr),+ ) => {
$crate::NcPlane::render($p)?;
$crate::NcPlane::rasterize($p)?;
sleep![$( $sleep_args ),+];
};
($nc:expr, $( $sleep_args:expr),+ ,) => {
rsleep![$nc, $( $sleep_args ),* ]
};
}
#[macro_export]
macro_rules! visual_render_sleep {
($v: expr, $vo: expr, $nc:expr, $( $sleep_args:expr),+ ) => {
unsafe { $crate::NcVisual::blit($v, $nc, Some($vo))? };
$crate::Nc::render($nc)?;
sleep![$( $sleep_args ),+];
};
($nc:expr, $( $sleep_args:expr),+ ,) => {
rsleep![$nc, $( $sleep_args ),* ]
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! cstring {
($s:expr) => {
std::ffi::CString::new($s).unwrap()
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! rstring {
($s:expr) => {
unsafe { core::ffi::CStr::from_ptr($s).to_str().unwrap() }
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! rstring_free {
($s:expr) => {{
#[allow(unused_unsafe)]
let nc_string = unsafe { $s };
let string = $crate::rstring![nc_string].to_string();
unsafe { $crate::c_api::libc::free(nc_string as *mut core::ffi::c_void) };
string
}};
}
#[macro_export]
#[doc(hidden)]
macro_rules! printf {
($s:expr) => {
let cs = cstring![$s];
unsafe { $crate::c_api::libc::printf(cs.as_ptr()) }
};
($s:expr $(, $opt:expr)*) => {
let cs = cstring![$s];
unsafe { $crate::c_api::libc::printf(cs.as_ptr(), $($opt),*) }
};
}
#[macro_export]
macro_rules! putstr {
($plane:ident, $($args:tt)*) => {
{
let res = $plane.putstr(&format![$($args)*])?;
$plane.render()?;
$plane.rasterize()?;
Ok(res)
}
};
}
#[macro_export]
macro_rules! putstrln {
($plane:ident) => {
{
$plane.putln()?;
$plane.render()?;
$plane.rasterize()?;
Ok(())
}
};
($plane:ident, $($args:tt)*) => {
{
let res = $plane.putstrln(&format![$($args)*])?;
$plane.render()?;
$plane.rasterize()?;
Ok(res)
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! error {
($res:expr, $msg:expr, $ok:expr) => {{
let res = $res;
if res >= $crate::c_api::NCRESULT_OK {
return Ok($ok);
} else {
return Err($crate::NcError::with_msg(res, $msg));
}
}};
($res:expr, $msg:expr) => {
error![$res, $msg, ()]
};
($res:expr) => {
error![$res, "", ()]
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! error_ref {
($ptr:expr, $msg:expr, $ok:expr) => {{
let ptr = $ptr; if ptr.is_null() {
return Err($crate::NcError::with_msg($crate::c_api::NCRESULT_ERR, $msg));
} else {
#[allow(unused_unsafe)]
return Ok(unsafe { $ok });
}
}};
($ptr:expr, $msg:expr) => {{
let ptr = $ptr;
error_ref![$ptr, $msg, unsafe { &*ptr }];
}};
($ptr:expr) => {{
let ptr = $ptr;
error_ref![$ptr, "", unsafe { &*ptr }];
}};
}
#[macro_export]
#[doc(hidden)]
macro_rules! error_ref_mut {
($ptr:expr, $msg:expr, $ok:expr) => {{
let ptr = $ptr; if ptr.is_null() {
return Err($crate::NcError::with_msg($crate::c_api::NCRESULT_ERR, $msg));
} else {
#[allow(unused_unsafe)]
return Ok(unsafe { $ok });
}
}};
($ptr:expr, $msg:expr) => {{
let ptr = $ptr;
error_ref_mut![ptr, $msg, unsafe { &mut *ptr }];
}};
($ptr:expr) => {{
let ptr = $ptr;
error_ref_mut![ptr, "", unsafe { &mut *ptr }];
}};
}
#[macro_export]
#[doc(hidden)]
macro_rules! error_str {
($str:expr, $msg:expr) => {
if !$str.is_null() {
#[allow(unused_unsafe)]
return Ok(unsafe { $crate::rstring!($str).to_string() });
} else {
return Err($crate::NcError::with_msg($crate::c_api::NCRESULT_ERR, $msg));
}
};
($str:expr) => {
error_str![$str, ""];
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! impl_api {
($type:ident, $trait:ident, $($i:item),*) => {
#[doc = concat!("Enables the [`", stringify!($type), "`] associated methods and constants.")]
pub trait $trait {
$($i)*
}
impl $trait for $type {
$($i)*
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! unit_impl_from [
($struct:ty, $prim:ty ) => {
impl From<$prim> for $struct {
fn from(p: $prim) -> Self { <$struct>::from_primitive(p) }
}
impl<'a> From<&'a $prim> for $struct {
fn from(p: &'a $prim) -> Self { <$struct>::from_primitive(*p) }
}
impl<'a> From<&'a mut $prim> for $struct {
fn from(p: &'a mut $prim) -> Self { <$struct>::from_primitive(*p) }
}
impl From<$struct> for $prim {
fn from(s: $struct) -> Self { s.0 }
}
impl<'a> From<&'a $struct> for &'a $prim {
fn from(s: &'a $struct) -> Self { &s.0 }
}
impl<'a> From<&'a mut $struct> for &'a mut $prim {
fn from(s: &'a mut $struct) -> Self { &mut s.0 }
}
impl From<&$struct> for *const $prim {
fn from(s: &$struct) -> Self { &s.0 as *const $prim}
}
impl From<&mut $struct> for *mut $prim {
fn from(s: &mut $struct) -> Self { &mut s.0 as *mut $prim}
}
};
];
#[macro_export]
#[doc(hidden)]
macro_rules! unit_impl_ops [
(bitwise; $outer:ty, $inner:ty) => {
$crate::unit_impl_ops![op_refs_u; Not, not, $outer];
$crate::unit_impl_ops![op_refs_ss; BitAnd, bitand, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss; BitOr, bitor, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss; BitXor, bitxor, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss; Shl, shl, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss; Shr, shr, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss_a; BitAndAssign, bitand_assign, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss_a; BitOrAssign, bitor_assign, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss_a; BitXorAssign, bitxor_assign, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss_a; ShlAssign, shl_assign, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss_a; ShrAssign, shr_assign, $outer, $outer];
$crate::unit_impl_ops![op_refs_sp; BitAnd, bitand, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp; BitOr, bitor, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp; BitXor, bitxor, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp; Shl, shl, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp; Shr, shr, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp_a; BitAndAssign, bitand_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp_a; BitOrAssign, bitor_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp_a; BitXorAssign, bitxor_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp_a; ShlAssign, shl_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp_a; ShrAssign, shr_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps; BitAnd, bitand, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps; BitOr, bitor, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps; BitXor, bitxor, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps; Shl, shl, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps; Shr, shr, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps_a; BitAndAssign, bitand_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps_a; BitOrAssign, bitor_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps_a; BitXorAssign, bitxor_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps_a; ShlAssign, shl_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps_a; ShrAssign, shr_assign, $outer, $inner];
};
(arithmetic; $outer:ty, $inner:ty) => {
$crate::unit_impl_ops![op_refs_ss; Add, add, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss; Sub, sub, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss; Mul, mul, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss; Div, div, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss; Rem, rem, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss; Rem, rem, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss_a; AndAssign, and_assign, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss_a; OrAssign, or_assign, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss_a; XorAssign, xor_assign, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss_a; ShlAssign, shl_assign, $outer, $outer];
$crate::unit_impl_ops![op_refs_ss_a; ShrAssign, shr_assign, $outer, $outer];
$crate::unit_impl_ops![op_refs_sp; Add, add, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp; Sub, sub, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp; Mul, mul, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp; Div, div, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp; Rem, rem, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp; Rem, rem, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp_a; AndAssign, and_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp_a; OrAssign, or_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp_a; XorAssign, xor_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp_a; ShlAssign, shl_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_sp_a; ShrAssign, shr_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps; Add, add, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps; Sub, sub, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps; Mul, mul, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps; Div, div, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps; Rem, rem, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps; Rem, rem, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps_a; AndAssign, and_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps_a; OrAssign, or_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps_a; XorAssign, xor_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps_a; ShlAssign, shl_assign, $outer, $inner];
$crate::unit_impl_ops![op_refs_ps_a; ShrAssign, shr_assign, $outer, $inner];
};
(neg; $type:ty) => {
$crate::unit_impl_ops![op_refs_u; Neg, neg, $type];
};
(op_refs_ss; $op:tt, $fn:ident, $T1:ty, $T2:ty) => {
$crate::unit_impl_ops![op_ss; $T1, $op, $fn, $T1, $T2];
$crate::unit_impl_ops![op_ss; $T1, $op, $fn, $T1, &'b $T2];
$crate::unit_impl_ops![op_ss; $T1, $op, $fn, $T1, &'b mut $T2];
$crate::unit_impl_ops![op_ss; $T1, $op, $fn, &'a $T1, $T2];
$crate::unit_impl_ops![op_ss; $T1, $op, $fn, &'a $T1, &'b $T2];
$crate::unit_impl_ops![op_ss; $T1, $op, $fn, &'a $T1, &'b mut $T2];
$crate::unit_impl_ops![op_ss; $T1, $op, $fn, &'a mut $T1, $T2];
$crate::unit_impl_ops![op_ss; $T1, $op, $fn, &'a mut $T1, &'b $T2];
$crate::unit_impl_ops![op_ss; $T1, $op, $fn, &'a mut $T1, &'b mut $T2];
};
(op_refs_sp; $op:tt, $fn:ident, $T1:ty, $T2:ty) => {
$crate::unit_impl_ops![op_sp; $T1, $op, $fn, $T1, $T2];
$crate::unit_impl_ops![op_sp; $T1, $op, $fn, $T1, &'b $T2];
$crate::unit_impl_ops![op_sp; $T1, $op, $fn, &'a $T1, $T2];
$crate::unit_impl_ops![op_sp; $T1, $op, $fn, &'a $T1, &'b $T2];
$crate::unit_impl_ops![op_sp; $T1, $op, $fn, &'a mut $T1, $T2];
$crate::unit_impl_ops![op_sp; $T1, $op, $fn, &'a mut $T1, &'b $T2];
};
(op_refs_ps; $op:tt, $fn:ident, $T1:ty, $T2:ty) => {
$crate::unit_impl_ops![op_ps; $T1, $op, $fn, $T2, $T1];
$crate::unit_impl_ops![op_ps; $T1, $op, $fn, $T2, &'b $T1];
$crate::unit_impl_ops![op_ps; $T1, $op, $fn, $T2, &'b mut $T1];
$crate::unit_impl_ops![op_ps; $T1, $op, $fn, &'a $T2, $T1];
$crate::unit_impl_ops![op_ps; $T1, $op, $fn, &'a $T2, &'b $T1];
$crate::unit_impl_ops![op_ps; $T1, $op, $fn, &'a $T2, &'b mut $T1];
};
(op_refs_ss_a; $op:tt, $fn:ident, $T1:ty, $T2:ty) => {
$crate::unit_impl_ops![op_ss_a; $op, $fn, $T1, $T2];
$crate::unit_impl_ops![op_ss_a; $op, $fn, $T1, &'b $T2];
$crate::unit_impl_ops![op_ss_a; $op, $fn, $T1, &'b mut $T2];
$crate::unit_impl_ops![op_ss_a; $op, $fn, &'a mut $T1, $T2];
$crate::unit_impl_ops![op_ss_a; $op, $fn, &'a mut $T1, &'b $T2];
$crate::unit_impl_ops![op_ss_a; $op, $fn, &'a mut $T1, &'b mut $T2];
};
(op_refs_sp_a; $op:tt, $fn:ident, $T1:ty, $T2:ty) => {
$crate::unit_impl_ops![op_sp_a; $op, $fn, $T1, $T2];
$crate::unit_impl_ops![op_sp_a; $op, $fn, $T1, &'b $T2];
$crate::unit_impl_ops![op_sp_a; $op, $fn, &'a mut $T1, $T2];
$crate::unit_impl_ops![op_sp_a; $op, $fn, &'a mut $T1, &'b $T2];
};
(op_refs_ps_a; $op:tt, $fn:ident, $T1:ty, $T2:ty) => {
$crate::unit_impl_ops![op_ps_a; $op, $fn, $T2, $T1];
$crate::unit_impl_ops![op_ps_a; $op, $fn, $T2, &'b $T1];
$crate::unit_impl_ops![op_ps_a; $op, $fn, $T2, &'b mut $T1];
};
(op_refs_u; $op:tt, $fn:ident, $T1:ty) => {
$crate::unit_impl_ops![op_u; $T1, $op, $fn, $T1];
$crate::unit_impl_ops![op_u; $T1, $op, $fn, &'a $T1];
$crate::unit_impl_ops![op_u; $T1, $op, $fn, &'a mut $T1];
};
(op_ss; $type:ty, $op:tt, $fn: ident, $for:ty, $rhs:ty) => {
#[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> core::ops::$op<$rhs> for $for {
type Output = $type;
fn $fn(self, rhs: $rhs) -> Self::Output {
<$type>::from_primitive(self.0.$fn(rhs.0))
}
}
};
(op_sp; $type:ty, $op:tt, $fn: ident, $for:ty, $rhs:ty) => {
#[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> core::ops::$op<$rhs> for $for {
type Output = $type;
fn $fn(self, rhs: $rhs) -> Self::Output {
<$type>::from_primitive(self.0.$fn(rhs))
}
}
};
(op_ps; $type:ty, $op:tt, $fn: ident, $for:ty, $rhs:ty) => {
#[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> core::ops::$op<$rhs> for $for {
type Output = $type;
fn $fn(self, rhs: $rhs) -> Self::Output {
<$type>::from_primitive(self.$fn(rhs.0))
}
}
};
(op_ss_a; $op:tt, $fn: ident, $for:ty, $rhs:ty) => {
#[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> core::ops::$op<$rhs> for $for {
fn $fn(&mut self, rhs: $rhs) {
self.0.$fn(rhs.0)
}
}
};
(op_sp_a; $op:tt, $fn: ident, $for:ty, $rhs:ty) => {
#[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> core::ops::$op<$rhs> for $for {
fn $fn(&mut self, rhs: $rhs) {
self.0.$fn(rhs)
}
}
};
(op_ps_a; $op:tt, $fn: ident, $for:ty, $rhs:ty) => {
#[allow(clippy::extra_unused_lifetimes)]
impl<'a, 'b> core::ops::$op<$rhs> for $for {
fn $fn(&mut self, rhs: $rhs) {
self.$fn(rhs.0)
}
}
};
(op_u; $type:ty, $op:tt, $fn: ident, $for:ty) => {
#[allow(clippy::extra_unused_lifetimes)]
impl<'a> core::ops::$op for $for {
type Output = $type;
fn $fn(self) -> Self::Output {
<$type>::from_primitive(self.0.$fn())
}
}
};
];
#[macro_export]
#[doc(hidden)]
macro_rules! unit_impl_fmt [
(all; $type:ty) => {
$crate::unit_impl_fmt![bases+display; $type];
$crate::unit_impl_fmt![scientific; $type];
};
(bases+display; $type:ty) => {
$crate::unit_impl_fmt![bases; $type];
$crate::unit_impl_fmt![display; $type];
};
(bases; $type:ty) => {
$crate::unit_impl_fmt![single; Binary, $type];
$crate::unit_impl_fmt![single; Octal, $type];
$crate::unit_impl_fmt![single; LowerHex, $type];
$crate::unit_impl_fmt![single; UpperHex, $type];
};
(scientific; $type:ty) => {
$crate::unit_impl_fmt![single; UpperExp, $type];
$crate::unit_impl_fmt![single; LowerExp, $type];
};
(display; $type:ty) => {
$crate::unit_impl_fmt![single; Display, $type];
};
(single; $trait:ident, $type:ty) => {
impl std::fmt::$trait for $type {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let val = self.0;
std::fmt::$trait::fmt(&val, f)
}
}
};
];
#[macro_export]
#[doc(hidden)]
macro_rules! from_primitive [
($outer:ty, $inner:ty) => {
impl $outer {
pub(crate) fn from_primitive(value: $inner) -> Self {
Self(value)
}
}
}
];