1#[allow(unused_imports)] use crate::{
8 c_api::{NCRESULT_ERR, NCRESULT_OK},
9 Nc, NcDirect, NcError, NcPlane, NcResult, NcVisual, NcVisualOptions,
10};
11
12#[macro_export]
18#[doc(hidden)]
19#[cfg(feature = "std")]
20macro_rules! cstring {
21 ($s:expr) => {
22 std::ffi::CString::new($s).unwrap()
23 };
24}
25
26#[macro_export]
30#[doc(hidden)]
31#[cfg(not(feature = "std"))]
32macro_rules! cstring {
33 ($s:expr) => {
34 alloc::ffi::CString::new($s).unwrap()
35 };
36}
37
38#[macro_export]
40#[doc(hidden)]
41macro_rules! rstring {
42 ($s:expr) => {
43 unsafe { core::ffi::CStr::from_ptr($s).to_str().unwrap() }
44 };
47}
48
49#[macro_export]
51#[doc(hidden)]
52#[cfg(feature = "std")]
53macro_rules! rstring_free {
54 ($s:expr) => {{
55 #[allow(unused_unsafe)]
56 let nc_string = unsafe { $s };
57 let string = $crate::rstring![nc_string].to_string();
58 unsafe { $crate::c_api::ffi::free(nc_string as *mut core::ffi::c_void) };
59 string
60 }};
61}
62
63#[macro_export]
65#[doc(hidden)]
66#[cfg(not(feature = "std"))]
67macro_rules! rstring_free {
68 ($s:expr) => {{
69 #[allow(unused_unsafe)]
70 let nc_string = unsafe { $s };
71 let string = alloc::string::ToString::to_string($crate::rstring![nc_string]);
72 unsafe { $crate::c_api::ffi::free(nc_string as *mut core::ffi::c_void) };
73 string
74 }};
75}
76
77#[macro_export]
79#[doc(hidden)]
80macro_rules! printf {
81 ($s:expr) => {
82 let cs = cstring![$s];
83 unsafe { $crate::c_api::libc::printf(cs.as_ptr()) }
84 };
85 ($s:expr $(, $opt:expr)*) => {
86 let cs = cstring![$s];
87 unsafe { $crate::c_api::libc::printf(cs.as_ptr(), $($opt),*) }
88 };
89}
90
91#[macro_export]
111macro_rules! putstr {
112 ($plane:ident, $($args:tt)*) => {
113 {
114 let res = $plane.putstr(&format![$($args)*])?;
115 $plane.render()?;
116 $plane.rasterize()?;
117 Ok(res)
118 }
119 };
120}
121
122#[macro_export]
142macro_rules! putstrln {
143 ($plane:ident) => {
144 {
145 $plane.putln()?;
146 $plane.render()?;
147 $plane.rasterize()?;
148 Ok(())
149 }
150 };
151 ($plane:ident, $($args:tt)*) => {
152 {
153 let res = $plane.putstrln(&format![$($args)*])?;
154 $plane.render()?;
155 $plane.rasterize()?;
156 Ok(res)
157 }
158 };
159}
160
161#[macro_export]
173#[doc(hidden)]
174macro_rules! error {
175 ($res:expr, $msg:expr, $ok:expr) => {{
176 let res = $res;
177 if res >= $crate::c_api::NCRESULT_OK {
178 return Ok($ok);
179 } else {
180 return Err($crate::NcError::with_msg(res, $msg));
181 }
182 }};
183 ($res:expr, $msg:expr) => {
184 error![$res, $msg, ()]
185 };
186 ($res:expr) => {
187 error![$res, "", ()]
188 };
189}
190
191#[macro_export]
200#[doc(hidden)]
201macro_rules! error_ref {
202 ($ptr:expr, $msg:expr, $ok:expr) => {{
203 let ptr = $ptr; if ptr.is_null() {
205 return Err($crate::NcError::with_msg($crate::c_api::NCRESULT_ERR, $msg));
206 } else {
207 #[allow(unused_unsafe)]
208 return Ok(unsafe { $ok });
209 }
210 }};
211 ($ptr:expr, $msg:expr) => {{
212 let ptr = $ptr;
213 error_ref![$ptr, $msg, unsafe { &*ptr }];
214 }};
215 ($ptr:expr) => {{
216 let ptr = $ptr;
217 error_ref![$ptr, "", unsafe { &*ptr }];
218 }};
219}
220
221#[macro_export]
230#[doc(hidden)]
231macro_rules! error_ref_mut {
232 ($ptr:expr, $msg:expr, $ok:expr) => {{
233 let ptr = $ptr; if ptr.is_null() {
235 return Err($crate::NcError::with_msg($crate::c_api::NCRESULT_ERR, $msg));
236 } else {
237 #[allow(unused_unsafe)]
238 return Ok(unsafe { $ok });
239 }
240 }};
241 ($ptr:expr, $msg:expr) => {{
242 let ptr = $ptr;
243 error_ref_mut![ptr, $msg, unsafe { &mut *ptr }];
244 }};
245 ($ptr:expr) => {{
246 let ptr = $ptr;
247 error_ref_mut![ptr, "", unsafe { &mut *ptr }];
248 }};
249}
250
251#[macro_export]
260#[doc(hidden)]
261#[cfg(feature = "std")]
262macro_rules! error_str {
263 ($str:expr, $msg:expr) => {
264 if !$str.is_null() {
265 #[allow(unused_unsafe)]
266 return Ok(unsafe { $crate::rstring!($str).to_string() });
267 } else {
268 return Err($crate::NcError::with_msg($crate::c_api::NCRESULT_ERR, $msg));
269 }
270 };
271 ($str:expr) => {
272 error_str![$str, ""];
273 };
274}
275
276#[macro_export]
285#[doc(hidden)]
286#[cfg(not(feature = "std"))]
287macro_rules! error_str {
288 ($str:expr, $msg:expr) => {
289 if !$str.is_null() {
290 #[allow(unused_unsafe)]
291 return Ok(unsafe { alloc::string::ToString::to_string($crate::rstring!($str)) });
292 } else {
293 return Err($crate::NcError::with_msg($crate::c_api::NCRESULT_ERR, $msg));
294 }
295 };
296 ($str:expr) => {
297 error_str![$str, ""];
298 };
299}
300
301#[macro_export]
308#[doc(hidden)]
309macro_rules! impl_api {
310 ($type:ident, $trait:ident, $($i:item),*) => {
311 #[doc = concat!("Enables the [`", stringify!($type), "`] associated methods and constants.")]
312 pub trait $trait {
313 $($i)*
314 }
315
316 impl $trait for $type {
317 $($i)*
318 }
319 };
320}
321
322#[macro_export]
325#[doc(hidden)]
326macro_rules! unit_impl_from [
327 ($struct:ty, $prim:ty ) => {
328 impl From<$prim> for $struct {
330 fn from(p: $prim) -> Self { <$struct>::from_primitive(p) }
331 }
332 impl<'a> From<&'a $prim> for $struct {
333 fn from(p: &'a $prim) -> Self { <$struct>::from_primitive(*p) }
334 }
335 impl<'a> From<&'a mut $prim> for $struct {
336 fn from(p: &'a mut $prim) -> Self { <$struct>::from_primitive(*p) }
337 }
338
339 impl From<$struct> for $prim {
341 fn from(s: $struct) -> Self { s.0 }
342 }
343 impl<'a> From<&'a $struct> for &'a $prim {
344 fn from(s: &'a $struct) -> Self { &s.0 }
345 }
346 impl<'a> From<&'a mut $struct> for &'a mut $prim {
347 fn from(s: &'a mut $struct) -> Self { &mut s.0 }
348 }
349 impl From<&$struct> for *const $prim {
350 fn from(s: &$struct) -> Self { &s.0 as *const $prim}
351 }
352 impl From<&mut $struct> for *mut $prim {
353 fn from(s: &mut $struct) -> Self { &mut s.0 as *mut $prim}
354 }
355 };
356];
357
358#[macro_export]
371#[doc(hidden)]
372macro_rules! unit_impl_ops [
373 (bitwise; $outer:ty, $inner:ty) => {
378 $crate::unit_impl_ops![op_refs_u; Not, not, $outer];
380 $crate::unit_impl_ops![op_refs_ss; BitAnd, bitand, $outer, $outer];
382 $crate::unit_impl_ops![op_refs_ss; BitOr, bitor, $outer, $outer];
383 $crate::unit_impl_ops![op_refs_ss; BitXor, bitxor, $outer, $outer];
384 $crate::unit_impl_ops![op_refs_ss; Shl, shl, $outer, $outer];
385 $crate::unit_impl_ops![op_refs_ss; Shr, shr, $outer, $outer];
386 $crate::unit_impl_ops![op_refs_ss_a; BitAndAssign, bitand_assign, $outer, $outer];
387 $crate::unit_impl_ops![op_refs_ss_a; BitOrAssign, bitor_assign, $outer, $outer];
388 $crate::unit_impl_ops![op_refs_ss_a; BitXorAssign, bitxor_assign, $outer, $outer];
389 $crate::unit_impl_ops![op_refs_ss_a; ShlAssign, shl_assign, $outer, $outer];
390 $crate::unit_impl_ops![op_refs_ss_a; ShrAssign, shr_assign, $outer, $outer];
391 $crate::unit_impl_ops![op_refs_sp; BitAnd, bitand, $outer, $inner];
393 $crate::unit_impl_ops![op_refs_sp; BitOr, bitor, $outer, $inner];
394 $crate::unit_impl_ops![op_refs_sp; BitXor, bitxor, $outer, $inner];
395 $crate::unit_impl_ops![op_refs_sp; Shl, shl, $outer, $inner];
396 $crate::unit_impl_ops![op_refs_sp; Shr, shr, $outer, $inner];
397 $crate::unit_impl_ops![op_refs_sp_a; BitAndAssign, bitand_assign, $outer, $inner];
398 $crate::unit_impl_ops![op_refs_sp_a; BitOrAssign, bitor_assign, $outer, $inner];
399 $crate::unit_impl_ops![op_refs_sp_a; BitXorAssign, bitxor_assign, $outer, $inner];
400 $crate::unit_impl_ops![op_refs_sp_a; ShlAssign, shl_assign, $outer, $inner];
401 $crate::unit_impl_ops![op_refs_sp_a; ShrAssign, shr_assign, $outer, $inner];
402 $crate::unit_impl_ops![op_refs_ps; BitAnd, bitand, $outer, $inner];
404 $crate::unit_impl_ops![op_refs_ps; BitOr, bitor, $outer, $inner];
405 $crate::unit_impl_ops![op_refs_ps; BitXor, bitxor, $outer, $inner];
406 $crate::unit_impl_ops![op_refs_ps; Shl, shl, $outer, $inner];
407 $crate::unit_impl_ops![op_refs_ps; Shr, shr, $outer, $inner];
408 $crate::unit_impl_ops![op_refs_ps_a; BitAndAssign, bitand_assign, $outer, $inner];
409 $crate::unit_impl_ops![op_refs_ps_a; BitOrAssign, bitor_assign, $outer, $inner];
410 $crate::unit_impl_ops![op_refs_ps_a; BitXorAssign, bitxor_assign, $outer, $inner];
411 $crate::unit_impl_ops![op_refs_ps_a; ShlAssign, shl_assign, $outer, $inner];
412 $crate::unit_impl_ops![op_refs_ps_a; ShrAssign, shr_assign, $outer, $inner];
413 };
414
415 (arithmetic; $outer:ty, $inner:ty) => {
417 $crate::unit_impl_ops![op_refs_ss; Add, add, $outer, $outer];
419 $crate::unit_impl_ops![op_refs_ss; Sub, sub, $outer, $outer];
420 $crate::unit_impl_ops![op_refs_ss; Mul, mul, $outer, $outer];
421 $crate::unit_impl_ops![op_refs_ss; Div, div, $outer, $outer];
422 $crate::unit_impl_ops![op_refs_ss; Rem, rem, $outer, $outer];
423 $crate::unit_impl_ops![op_refs_ss; Rem, rem, $outer, $outer];
424 $crate::unit_impl_ops![op_refs_ss_a; AndAssign, and_assign, $outer, $outer];
425 $crate::unit_impl_ops![op_refs_ss_a; OrAssign, or_assign, $outer, $outer];
426 $crate::unit_impl_ops![op_refs_ss_a; XorAssign, xor_assign, $outer, $outer];
427 $crate::unit_impl_ops![op_refs_ss_a; ShlAssign, shl_assign, $outer, $outer];
428 $crate::unit_impl_ops![op_refs_ss_a; ShrAssign, shr_assign, $outer, $outer];
429 $crate::unit_impl_ops![op_refs_sp; Add, add, $outer, $inner];
431 $crate::unit_impl_ops![op_refs_sp; Sub, sub, $outer, $inner];
432 $crate::unit_impl_ops![op_refs_sp; Mul, mul, $outer, $inner];
433 $crate::unit_impl_ops![op_refs_sp; Div, div, $outer, $inner];
434 $crate::unit_impl_ops![op_refs_sp; Rem, rem, $outer, $inner];
435 $crate::unit_impl_ops![op_refs_sp; Rem, rem, $outer, $inner];
436 $crate::unit_impl_ops![op_refs_sp_a; AndAssign, and_assign, $outer, $inner];
437 $crate::unit_impl_ops![op_refs_sp_a; OrAssign, or_assign, $outer, $inner];
438 $crate::unit_impl_ops![op_refs_sp_a; XorAssign, xor_assign, $outer, $inner];
439 $crate::unit_impl_ops![op_refs_sp_a; ShlAssign, shl_assign, $outer, $inner];
440 $crate::unit_impl_ops![op_refs_sp_a; ShrAssign, shr_assign, $outer, $inner];
441 $crate::unit_impl_ops![op_refs_ps; Add, add, $outer, $inner];
443 $crate::unit_impl_ops![op_refs_ps; Sub, sub, $outer, $inner];
444 $crate::unit_impl_ops![op_refs_ps; Mul, mul, $outer, $inner];
445 $crate::unit_impl_ops![op_refs_ps; Div, div, $outer, $inner];
446 $crate::unit_impl_ops![op_refs_ps; Rem, rem, $outer, $inner];
447 $crate::unit_impl_ops![op_refs_ps; Rem, rem, $outer, $inner];
448 $crate::unit_impl_ops![op_refs_ps_a; AndAssign, and_assign, $outer, $inner];
449 $crate::unit_impl_ops![op_refs_ps_a; OrAssign, or_assign, $outer, $inner];
450 $crate::unit_impl_ops![op_refs_ps_a; XorAssign, xor_assign, $outer, $inner];
451 $crate::unit_impl_ops![op_refs_ps_a; ShlAssign, shl_assign, $outer, $inner];
452 $crate::unit_impl_ops![op_refs_ps_a; ShrAssign, shr_assign, $outer, $inner];
453 };
454
455 (neg; $type:ty) => {
457 $crate::unit_impl_ops![op_refs_u; Neg, neg, $type];
458 };
459
460 (op_refs_ss; $op:tt, $fn:ident, $T1:ty, $T2:ty) => {
467 $crate::unit_impl_ops![op_ss; $T1, $op, $fn, $T1, $T2];
468 $crate::unit_impl_ops![op_ss; $T1, $op, $fn, $T1, &'b $T2];
469 $crate::unit_impl_ops![op_ss; $T1, $op, $fn, $T1, &'b mut $T2];
470 $crate::unit_impl_ops![op_ss; $T1, $op, $fn, &'a $T1, $T2];
471 $crate::unit_impl_ops![op_ss; $T1, $op, $fn, &'a $T1, &'b $T2];
472 $crate::unit_impl_ops![op_ss; $T1, $op, $fn, &'a $T1, &'b mut $T2];
473 $crate::unit_impl_ops![op_ss; $T1, $op, $fn, &'a mut $T1, $T2];
474 $crate::unit_impl_ops![op_ss; $T1, $op, $fn, &'a mut $T1, &'b $T2];
475 $crate::unit_impl_ops![op_ss; $T1, $op, $fn, &'a mut $T1, &'b mut $T2];
476 };
477 (op_refs_sp; $op:tt, $fn:ident, $T1:ty, $T2:ty) => {
479 $crate::unit_impl_ops![op_sp; $T1, $op, $fn, $T1, $T2];
480 $crate::unit_impl_ops![op_sp; $T1, $op, $fn, $T1, &'b $T2];
481 $crate::unit_impl_ops![op_sp; $T1, $op, $fn, &'a $T1, $T2];
482 $crate::unit_impl_ops![op_sp; $T1, $op, $fn, &'a $T1, &'b $T2];
483 $crate::unit_impl_ops![op_sp; $T1, $op, $fn, &'a mut $T1, $T2];
484 $crate::unit_impl_ops![op_sp; $T1, $op, $fn, &'a mut $T1, &'b $T2];
485 };
490 (op_refs_ps; $op:tt, $fn:ident, $T1:ty, $T2:ty) => {
492 $crate::unit_impl_ops![op_ps; $T1, $op, $fn, $T2, $T1];
493 $crate::unit_impl_ops![op_ps; $T1, $op, $fn, $T2, &'b $T1];
494 $crate::unit_impl_ops![op_ps; $T1, $op, $fn, $T2, &'b mut $T1];
495 $crate::unit_impl_ops![op_ps; $T1, $op, $fn, &'a $T2, $T1];
496 $crate::unit_impl_ops![op_ps; $T1, $op, $fn, &'a $T2, &'b $T1];
497 $crate::unit_impl_ops![op_ps; $T1, $op, $fn, &'a $T2, &'b mut $T1];
498 };
503
504 (op_refs_ss_a; $op:tt, $fn:ident, $T1:ty, $T2:ty) => {
508 $crate::unit_impl_ops![op_ss_a; $op, $fn, $T1, $T2];
509 $crate::unit_impl_ops![op_ss_a; $op, $fn, $T1, &'b $T2];
510 $crate::unit_impl_ops![op_ss_a; $op, $fn, $T1, &'b mut $T2];
511 $crate::unit_impl_ops![op_ss_a; $op, $fn, &'a mut $T1, $T2];
512 $crate::unit_impl_ops![op_ss_a; $op, $fn, &'a mut $T1, &'b $T2];
513 $crate::unit_impl_ops![op_ss_a; $op, $fn, &'a mut $T1, &'b mut $T2];
514 };
515 (op_refs_sp_a; $op:tt, $fn:ident, $T1:ty, $T2:ty) => {
517 $crate::unit_impl_ops![op_sp_a; $op, $fn, $T1, $T2];
518 $crate::unit_impl_ops![op_sp_a; $op, $fn, $T1, &'b $T2];
519 $crate::unit_impl_ops![op_sp_a; $op, $fn, &'a mut $T1, $T2];
520 $crate::unit_impl_ops![op_sp_a; $op, $fn, &'a mut $T1, &'b $T2];
521 };
525 (op_refs_ps_a; $op:tt, $fn:ident, $T1:ty, $T2:ty) => {
527 $crate::unit_impl_ops![op_ps_a; $op, $fn, $T2, $T1];
528 $crate::unit_impl_ops![op_ps_a; $op, $fn, $T2, &'b $T1];
529 $crate::unit_impl_ops![op_ps_a; $op, $fn, $T2, &'b mut $T1];
530 };
535
536 (op_refs_u; $op:tt, $fn:ident, $T1:ty) => {
538 $crate::unit_impl_ops![op_u; $T1, $op, $fn, $T1];
539 $crate::unit_impl_ops![op_u; $T1, $op, $fn, &'a $T1];
540 $crate::unit_impl_ops![op_u; $T1, $op, $fn, &'a mut $T1];
541 };
542
543 (op_ss; $type:ty, $op:tt, $fn: ident, $for:ty, $rhs:ty) => {
559 #[allow(clippy::extra_unused_lifetimes)]
560 impl<'a, 'b> core::ops::$op<$rhs> for $for {
561 type Output = $type;
562 fn $fn(self, rhs: $rhs) -> Self::Output {
563 <$type>::from_primitive(self.0.$fn(rhs.0))
564 }
565 }
566 };
567 (op_sp; $type:ty, $op:tt, $fn: ident, $for:ty, $rhs:ty) => {
569 #[allow(clippy::extra_unused_lifetimes)]
570 impl<'a, 'b> core::ops::$op<$rhs> for $for {
571 type Output = $type;
572 fn $fn(self, rhs: $rhs) -> Self::Output {
573 <$type>::from_primitive(self.0.$fn(rhs))
574 }
575 }
576 };
577 (op_ps; $type:ty, $op:tt, $fn: ident, $for:ty, $rhs:ty) => {
579 #[allow(clippy::extra_unused_lifetimes)]
580 impl<'a, 'b> core::ops::$op<$rhs> for $for {
581 type Output = $type;
582 fn $fn(self, rhs: $rhs) -> Self::Output {
583 <$type>::from_primitive(self.$fn(rhs.0))
584 }
585 }
586 };
587
588 (op_ss_a; $op:tt, $fn: ident, $for:ty, $rhs:ty) => {
592 #[allow(clippy::extra_unused_lifetimes)]
593 impl<'a, 'b> core::ops::$op<$rhs> for $for {
594 fn $fn(&mut self, rhs: $rhs) {
595 self.0.$fn(rhs.0)
596 }
597 }
598 };
599 (op_sp_a; $op:tt, $fn: ident, $for:ty, $rhs:ty) => {
601 #[allow(clippy::extra_unused_lifetimes)]
602 impl<'a, 'b> core::ops::$op<$rhs> for $for {
603 fn $fn(&mut self, rhs: $rhs) {
604 self.0.$fn(rhs)
605 }
606 }
607 };
608 (op_ps_a; $op:tt, $fn: ident, $for:ty, $rhs:ty) => {
610 #[allow(clippy::extra_unused_lifetimes)]
611 impl<'a, 'b> core::ops::$op<$rhs> for $for {
612 fn $fn(&mut self, rhs: $rhs) {
613 self.$fn(rhs.0)
614 }
615 }
616 };
617
618 (op_u; $type:ty, $op:tt, $fn: ident, $for:ty) => {
620 #[allow(clippy::extra_unused_lifetimes)]
621 impl<'a> core::ops::$op for $for {
622 type Output = $type;
623 fn $fn(self) -> Self::Output {
624 <$type>::from_primitive(self.0.$fn())
625 }
626 }
627 };
628];
629
630#[macro_export]
632#[doc(hidden)]
633macro_rules! unit_impl_fmt [
634 (all; $type:ty) => {
635 $crate::unit_impl_fmt![bases+display; $type];
636 $crate::unit_impl_fmt![scientific; $type];
637 };
638
639 (bases+display; $type:ty) => {
640 $crate::unit_impl_fmt![bases; $type];
641 $crate::unit_impl_fmt![display; $type];
642 };
643
644 (bases; $type:ty) => {
645 $crate::unit_impl_fmt![single; Binary, $type];
646 $crate::unit_impl_fmt![single; Octal, $type];
647 $crate::unit_impl_fmt![single; LowerHex, $type];
648 $crate::unit_impl_fmt![single; UpperHex, $type];
649 };
650
651 (scientific; $type:ty) => {
652 $crate::unit_impl_fmt![single; UpperExp, $type];
653 $crate::unit_impl_fmt![single; LowerExp, $type];
654 };
655
656 (display; $type:ty) => {
657 $crate::unit_impl_fmt![single; Display, $type];
658 };
659
660 (single; $trait:ident, $type:ty) => {
661 impl core::fmt::$trait for $type {
662 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
663 let val = self.0;
664 core::fmt::$trait::fmt(&val, f)
665 }
666 }
667 };
668];
669
670#[macro_export]
673#[doc(hidden)]
674macro_rules! from_primitive [
675 ($outer:ty, $inner:ty) => {
676 impl $outer {
677 pub(crate) fn from_primitive(value: $inner) -> Self {
678 Self(value)
679 }
680 }
681 }
682];