Skip to content

Commit 2774f40

Browse files
committed
glib: Add function_name! macro and make use of that for glib::BoolError
Let's get the actual function name as this is a lot more useful for debugging purposes.
1 parent 419f13f commit 2774f40

File tree

2 files changed

+69
-10
lines changed

2 files changed

+69
-10
lines changed

glib/src/error.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,30 +158,46 @@ pub trait ErrorDomain: Copy {
158158
#[macro_export]
159159
macro_rules! bool_error(
160160
// Plain strings
161-
($msg:expr) => {
162-
$crate::BoolError::new($msg, file!(), module_path!(), line!())
163-
};
161+
($msg:expr) => {{
162+
$crate::BoolError::new(
163+
$msg,
164+
file!(),
165+
$crate::function_name!(),
166+
line!(),
167+
)
168+
}};
164169

165170
// Format strings
166-
($($msg:tt)*) => { {
167-
$crate::BoolError::new(format!($($msg)*), file!(), module_path!(), line!())
171+
($($msg:tt)*) => {{
172+
$crate::BoolError::new(
173+
format!($($msg)*),
174+
file!(),
175+
$crate::function_name!(),
176+
line!(),
177+
)
168178
}};
169179
);
170180

171181
#[macro_export]
172182
macro_rules! result_from_gboolean(
173183
// Plain strings
174-
($ffi_bool:expr, $msg:expr) => {
175-
$crate::BoolError::from_glib($ffi_bool, $msg, file!(), module_path!(), line!())
176-
};
184+
($ffi_bool:expr, $msg:expr) => {{
185+
$crate::BoolError::from_glib(
186+
$ffi_bool,
187+
$msg,
188+
file!(),
189+
$crate::function_name!(),
190+
line!(),
191+
)
192+
}};
177193

178194
// Format strings
179-
($ffi_bool:expr, $($msg:tt)*) => { {
195+
($ffi_bool:expr, $($msg:tt)*) => {{
180196
$crate::BoolError::from_glib(
181197
$ffi_bool,
182198
format!($($msg)*),
183199
file!(),
184-
module_path!(),
200+
$crate::function_name!(),
185201
line!(),
186202
)
187203
}};

glib/src/lib.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,49 @@ pub use self::variant_dict::VariantDict;
4848
pub use self::variant_iter::{VariantIter, VariantStrIter};
4949
pub use self::variant_type::{VariantTy, VariantTyIterator, VariantType};
5050

51+
// Hack for the time being to retrieve the current function's name as a string.
52+
// Based on the stdext cratelicensed under the MIT license.
53+
//
54+
// Copyright (c) 2020 Igor Aleksanov
55+
//
56+
// Previous attempts to get such a macro into std:
57+
// * https://github.com/rust-lang/rfcs/pull/466
58+
// * https://github.com/rust-lang/rfcs/pull/1719
59+
// * https://github.com/rust-lang/rfcs/issues/1743
60+
// * https://github.com/rust-lang/rfcs/pull/2818
61+
// * ...
62+
// rustdoc-stripper-ignore-next
63+
/// This macro returns the name of the enclosing function.
64+
/// As the internal implementation is based on the [`std::any::type_name`], this macro derives
65+
/// all the limitations of this function.
66+
///
67+
/// ## Examples
68+
///
69+
/// ```rust
70+
/// mod bar {
71+
/// pub fn sample_function() {
72+
/// assert!(glib::function_name!().ends_with("bar::sample_function"));
73+
/// }
74+
/// }
75+
///
76+
/// bar::sample_function();
77+
/// ```
78+
///
79+
/// [`std::any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html
80+
#[macro_export]
81+
macro_rules! function_name {
82+
() => {{
83+
// Okay, this is ugly, I get it. However, this is the best we can get on a stable rust.
84+
fn f() {}
85+
fn type_name_of<T>(_: T) -> &'static str {
86+
std::any::type_name::<T>()
87+
}
88+
let name = type_name_of(f);
89+
// `3` is the length of the `::f`.
90+
&name[..name.len() - 3]
91+
}};
92+
}
93+
5194
pub mod clone;
5295
#[macro_use]
5396
pub mod wrapper;

0 commit comments

Comments
 (0)