gfxd_rs/printer.rs
1/* SPDX-FileCopyrightText: © 2025 Decompollaborate */
2/* SPDX-License-Identifier: MIT OR Apache-2.0 */
3
4use gfxd_sys::ptr::NonNullConst;
5
6use crate::{ArgType, ArgValue, MacroFnRet};
7
8/// An utility that allows writing to `gfxd`'s output buffer from inside
9/// user-defined callbacks.
10pub struct Printer {
11 // Placeholder to avoid constructing this type
12 _unit: (),
13}
14
15/// An utility to write to `gfxd`'s output buffer from macro-specific
16/// user-defined callbacks.
17pub struct MacroPrinter {
18 printer: Printer,
19}
20
21impl Printer {
22 // It should not be possible to construct this type by library consumers.
23 pub(crate) const fn new() -> Self {
24 Self { _unit: () }
25 }
26
27 /// Write the given str to the output buffer.
28 pub fn write_str(&mut self, s: &str) {
29 let buf = NonNullConst::from_ref(s).cast();
30 // s.len() is the number of bytes in str instead of number of chars
31 #[allow(clippy::cast_possible_truncation)]
32 let len = s.len() as _;
33
34 unsafe {
35 gfxd_sys::custom_output::gfxd_write(buf, len);
36 }
37 }
38
39 /// Write the given Argument Value to the output buffer.
40 pub fn write_arg_value(&mut self, typ: ArgType, value: &ArgValue) {
41 let (_, v) = value.to_gfxd_value();
42 let ptr = NonNullConst::from_ref(&v);
43
44 unsafe {
45 gfxd_sys::custom_output::gfxd_print_value(typ.into(), ptr);
46 }
47 }
48}
49
50impl MacroPrinter {
51 // It should not be possible to construct this type by library consumers.
52 pub(crate) const fn new() -> Self {
53 Self {
54 printer: Printer::new(),
55 }
56 }
57
58 /// Write the given str to the output buffer.
59 pub fn write_str(&mut self, s: &str) {
60 self.printer.write_str(s);
61 }
62
63 /// Write the given Argument Value to the output buffer.
64 pub fn write_arg_value(&mut self, typ: ArgType, value: &ArgValue) {
65 self.printer.write_arg_value(typ, value);
66 }
67
68 /// The default macro handler.
69 ///
70 /// Outputs the macro name, dynamic display list pointer if one has been
71 /// specified, and then each argument in order using the function
72 /// registered using [`arg_fn`] ([`arg_dflt`] by default).
73 ///
74 /// Because it is designed to be extended, it only outputs the macro text,
75 /// without any whitespace or punctuation before or after.
76 ///
77 /// [`arg_fn`]: crate::Customizer::arg_fn
78 /// [`arg_dflt`]: MacroPrinter::arg_dflt
79 pub fn macro_dflt(&mut self) -> MacroFnRet {
80 let ret = unsafe { gfxd_sys::handlers::gfxd_macro_dflt() };
81
82 match ret {
83 0 => MacroFnRet::Continue,
84 _ => MacroFnRet::Stop,
85 }
86 }
87
88 /// The default argument handler for [`macro_dflt`].
89 ///
90 /// For the argument with index `arg_num`, calls `arg_callbacks`, and
91 /// prints the argument value if the callback returns zero, or if there is
92 /// no callback for the given argument.
93 ///
94 /// [`macro_dflt`]: MacroPrinter::macro_dflt
95 pub fn arg_dflt(&mut self, arg_num: i32) {
96 unsafe {
97 gfxd_sys::handlers::gfxd_arg_dflt(arg_num as _);
98 }
99 }
100}