godot_core/global/print.rs
1/*
2 * Copyright (c) godot-rust; Bromeon and contributors.
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6 */
7
8//! Printing and logging functionality.
9
10// https://stackoverflow.com/a/40234666
11#[macro_export]
12#[doc(hidden)]
13macro_rules! inner_function {
14 () => {{
15 fn f() {}
16 fn type_name_of<T>(_: T) -> &'static str {
17 std::any::type_name::<T>()
18 }
19 let name = type_name_of(f);
20 name.strip_suffix("::f").unwrap()
21 }};
22}
23
24#[macro_export]
25#[doc(hidden)]
26macro_rules! inner_godot_msg {
27 // FIXME expr needs to be parenthesised, see usages
28 ($godot_fn:ident; $fmt:literal $(, $args:expr)* $(,)?) => {
29 //($($args:tt),* $(,)?) => {
30 unsafe {
31 let msg = format!("{}\0", format_args!($fmt $(, $args)*));
32 // Godot supports Unicode messages, not only ASCII. See `do_panic` test.
33
34 // Check whether engine is loaded, otherwise fall back to stderr.
35 if $crate::sys::is_initialized() {
36 let function = format!("{}\0", $crate::inner_function!());
37 $crate::sys::interface_fn!($godot_fn)(
38 $crate::sys::c_str_from_str(&msg),
39 $crate::sys::c_str_from_str(&function),
40 $crate::sys::c_str_from_str(concat!(file!(), "\0")),
41 line!() as i32,
42 false as $crate::sys::GDExtensionBool, // whether to create a toast notification in editor
43 );
44 } else {
45 eprintln!("[{}] {}", stringify!($godot_fn), &msg[..msg.len() - 1]);
46 }
47 }
48 };
49}
50
51/// Pushes a warning message to Godot's built-in debugger and to the OS terminal.
52///
53/// # See also
54/// [`godot_print!`](macro.godot_print.html) and [`godot_error!`](macro.godot_error.html).
55///
56/// Related to the utility function [`global::push_warning()`](crate::global::push_warning).
57///
58/// _Godot equivalent: [`@GlobalScope.push_warning()`](https://docs.godotengine.org/en/stable/classes/class_@globalscope.html#class-globalscope-method-push-warning)_.
59#[macro_export]
60macro_rules! godot_warn {
61 ($fmt:literal $(, $args:expr)* $(,)?) => {
62 $crate::inner_godot_msg!(print_warning; $fmt $(, $args)*);
63 };
64}
65
66/// Pushes an error message to Godot's built-in debugger and to the OS terminal.
67///
68/// # See also
69/// [`godot_print!`](macro.godot_print.html) and [`godot_warn!`](macro.godot_warn.html).
70/// For script errors (less relevant in Rust), use [`godot_script_error!`](macro.godot_script_error.html).
71///
72/// Related to the utility function [`global::push_error()`][crate::global::push_error].
73///
74/// _Godot equivalent: [`@GlobalScope.push_error()`](https://docs.godotengine.org/en/stable/classes/class_@globalscope.html#class-globalscope-method-push-error)_.
75#[macro_export]
76macro_rules! godot_error {
77 ($fmt:literal $(, $args:expr)* $(,)?) => {
78 $crate::inner_godot_msg!(print_error; $fmt $(, $args)*);
79 };
80}
81
82/// Logs a script error to Godot's built-in debugger and to the OS terminal.
83///
84/// This is rarely needed in Rust; script errors are typically emitted by the GDScript parser.
85///
86/// # See also
87/// [`godot_error!`](macro.godot_error.html) for a general error message.
88///
89///
90#[macro_export]
91macro_rules! godot_script_error {
92 ($fmt:literal $(, $args:expr)* $(,)?) => {
93 $crate::inner_godot_msg!(print_script_error; $fmt $(, $args)*);
94 };
95}
96
97/// Prints to the Godot console.
98///
99/// Automatically appends a newline character at the end of the message.
100///
101/// Used exactly like standard [`println!`]:
102/// ```no_run
103/// use godot::global::godot_print;
104///
105/// let version = 4;
106/// godot_print!("Hello, Godot {version}!");
107/// ```
108///
109/// # See also
110/// [`godot_print_rich!`](macro.godot_print_rich.html) for a slower alternative that supports BBCode, color and URL tags.
111/// To print Godot errors and warnings, use [`godot_error!`](macro.godot_error.html) and [`godot_warn!`](macro.godot_warn.html), respectively.
112///
113/// This uses the underlying [`global::print()`][crate::global::print] function, which takes a variable-length slice of variants.
114///
115/// _Godot equivalent: [`@GlobalScope.print()`](https://docs.godotengine.org/en/stable/classes/class_@globalscope.html#class-globalscope-method-print)_.
116#[macro_export]
117macro_rules! godot_print {
118 ($fmt:literal $(, $args:expr)* $(,)?) => {
119 $crate::global::print(&[
120 $crate::builtin::Variant::from(
121 format!($fmt $(, $args)*)
122 )
123 ])
124 };
125}
126
127/// Prints to the Godot console. Supports BBCode, color and URL tags.
128///
129/// Slower than [`godot_print!`](macro.godot_print_rich.html).
130///
131/// _Godot equivalent: [`@GlobalScope.print_rich()`](https://docs.godotengine.org/en/stable/classes/class_@globalscope.html#class-globalscope-method-print-rich)_.
132#[macro_export]
133macro_rules! godot_print_rich {
134 ($fmt:literal $(, $args:expr)* $(,)?) => {
135 $crate::global::print_rich(&[
136 $crate::builtin::Variant::from(
137 format!($fmt $(, $args)*)
138 )
139 ])
140 };
141}
142
143/// Concatenates format-style arguments into a `GString`.
144///
145/// Works similar to Rust's standard [`format!`] macro but returns a Godot `GString`.
146///
147/// # Example
148/// ```no_run
149/// use godot::builtin::GString;
150/// use godot::global::godot_str;
151///
152/// let name = "Player";
153/// let score = 100;
154/// let message: GString = godot_str!("The {name} scored {score} points!");
155/// ```
156///
157/// # See also
158/// This macro uses the underlying [`global::str()`][crate::global::str] function, which takes a variable-length slice of variants.
159///
160/// _Godot equivalent: [`@GlobalScope.str()`](https://docs.godotengine.org/en/stable/classes/class_@globalscope.html#class-globalscope-method-str)_.
161#[macro_export]
162macro_rules! godot_str {
163 ($fmt:literal $(, $args:expr)* $(,)?) => {
164 $crate::global::str(&[
165 $crate::builtin::Variant::from(
166 format!($fmt $(, $args)*)
167 )
168 ])
169 };
170}