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}