1#[cfg(unix)]
4use std::os::unix::io::{AsFd, AsRawFd};
5use std::{
6 boxed::Box as Box_,
7 sync::{Arc, Mutex, OnceLock},
8};
9
10#[cfg(feature = "v2_80")]
11use crate::StrVRef;
12use crate::{GStr, GString, LogWriterOutput, ffi, translate::*};
13
14#[derive(Debug)]
15pub struct LogHandlerId(u32);
16
17#[doc(hidden)]
18impl FromGlib<u32> for LogHandlerId {
19 #[inline]
20 unsafe fn from_glib(value: u32) -> Self {
21 Self(value)
22 }
23}
24
25#[doc(hidden)]
26impl IntoGlib for LogHandlerId {
27 type GlibType = u32;
28
29 #[inline]
30 fn into_glib(self) -> u32 {
31 self.0
32 }
33}
34
35#[derive(Copy, Clone, Debug, PartialEq, Eq)]
36pub enum LogLevel {
37 #[doc(alias = "G_LOG_LEVEL_ERROR")]
38 Error,
39 #[doc(alias = "G_LOG_LEVEL_CRITICAL")]
40 Critical,
41 #[doc(alias = "G_LOG_LEVEL_WARNING")]
42 Warning,
43 #[doc(alias = "G_LOG_LEVEL_MESSAGE")]
44 Message,
45 #[doc(alias = "G_LOG_LEVEL_INFO")]
46 Info,
47 #[doc(alias = "G_LOG_LEVEL_DEBUG")]
48 Debug,
49}
50
51#[doc(hidden)]
52impl IntoGlib for LogLevel {
53 type GlibType = u32;
54
55 #[inline]
56 fn into_glib(self) -> u32 {
57 match self {
58 Self::Error => ffi::G_LOG_LEVEL_ERROR,
59 Self::Critical => ffi::G_LOG_LEVEL_CRITICAL,
60 Self::Warning => ffi::G_LOG_LEVEL_WARNING,
61 Self::Message => ffi::G_LOG_LEVEL_MESSAGE,
62 Self::Info => ffi::G_LOG_LEVEL_INFO,
63 Self::Debug => ffi::G_LOG_LEVEL_DEBUG,
64 }
65 }
66}
67
68#[doc(hidden)]
69impl FromGlib<u32> for LogLevel {
70 #[inline]
71 unsafe fn from_glib(value: u32) -> Self {
72 if value & ffi::G_LOG_LEVEL_ERROR != 0 {
73 Self::Error
74 } else if value & ffi::G_LOG_LEVEL_CRITICAL != 0 {
75 Self::Critical
76 } else if value & ffi::G_LOG_LEVEL_WARNING != 0 {
77 Self::Warning
78 } else if value & ffi::G_LOG_LEVEL_MESSAGE != 0 {
79 Self::Message
80 } else if value & ffi::G_LOG_LEVEL_INFO != 0 {
81 Self::Info
82 } else if value & ffi::G_LOG_LEVEL_DEBUG != 0 {
83 Self::Debug
84 } else {
85 panic!("Unknown log level: {value}")
86 }
87 }
88}
89
90impl LogLevel {
91 #[doc(hidden)]
92 pub fn priority(&self) -> &'static str {
93 match self {
94 Self::Error => "3",
95 Self::Critical => "4",
96 Self::Warning => "4",
97 Self::Message => "5",
98 Self::Info => "6",
99 Self::Debug => "7",
100 }
101 }
102}
103
104bitflags::bitflags! {
105 #[doc(alias = "GLogLevelFlags")]
106 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
107 pub struct LogLevels: u32 {
108 #[doc(alias = "G_LOG_LEVEL_ERROR")]
109 const LEVEL_ERROR = ffi::G_LOG_LEVEL_ERROR;
110 #[doc(alias = "G_LOG_LEVEL_CRITICAL")]
111 const LEVEL_CRITICAL = ffi::G_LOG_LEVEL_CRITICAL;
112 #[doc(alias = "G_LOG_LEVEL_WARNING")]
113 const LEVEL_WARNING = ffi::G_LOG_LEVEL_WARNING;
114 #[doc(alias = "G_LOG_LEVEL_MESSAGE")]
115 const LEVEL_MESSAGE = ffi::G_LOG_LEVEL_MESSAGE;
116 #[doc(alias = "G_LOG_LEVEL_INFO")]
117 const LEVEL_INFO = ffi::G_LOG_LEVEL_INFO;
118 #[doc(alias = "G_LOG_LEVEL_DEBUG")]
119 const LEVEL_DEBUG = ffi::G_LOG_LEVEL_DEBUG;
120 }
121}
122
123#[doc(hidden)]
124impl IntoGlib for LogLevels {
125 type GlibType = ffi::GLogLevelFlags;
126
127 #[inline]
128 fn into_glib(self) -> ffi::GLogLevelFlags {
129 self.bits()
130 }
131}
132
133#[doc(hidden)]
134impl FromGlib<ffi::GLogLevelFlags> for LogLevels {
135 #[inline]
136 unsafe fn from_glib(value: ffi::GLogLevelFlags) -> Self {
137 Self::from_bits_truncate(value)
138 }
139}
140
141fn to_log_flags(fatal: bool, recursion: bool) -> u32 {
142 (if fatal { ffi::G_LOG_FLAG_FATAL } else { 0 })
143 | if recursion {
144 ffi::G_LOG_FLAG_RECURSION
145 } else {
146 0
147 }
148}
149
150#[doc(alias = "g_log_set_handler_full")]
151pub fn log_set_handler<P: Fn(Option<&str>, LogLevel, &str) + Send + Sync + 'static>(
152 log_domain: Option<&str>,
153 log_levels: LogLevels,
154 fatal: bool,
155 recursion: bool,
156 log_func: P,
157) -> LogHandlerId {
158 let log_func_data: Box_<P> = Box_::new(log_func);
159 unsafe extern "C" fn log_func_func<
160 P: Fn(Option<&str>, LogLevel, &str) + Send + Sync + 'static,
161 >(
162 log_domain: *const libc::c_char,
163 log_level: ffi::GLogLevelFlags,
164 message: *const libc::c_char,
165 user_data: ffi::gpointer,
166 ) {
167 unsafe {
168 let log_domain: Borrowed<Option<GString>> = from_glib_borrow(log_domain);
169 let message: Borrowed<GString> = from_glib_borrow(message);
170 let callback: &P = &*(user_data as *mut _);
171 (*callback)(
172 (*log_domain).as_ref().map(|s| s.as_str()),
173 from_glib(log_level),
174 message.as_str(),
175 );
176 }
177 }
178 let log_func = Some(log_func_func::<P> as _);
179 unsafe extern "C" fn destroy_func<
180 P: Fn(Option<&str>, LogLevel, &str) + Send + Sync + 'static,
181 >(
182 data: ffi::gpointer,
183 ) {
184 unsafe {
185 let _callback: Box_<P> = Box_::from_raw(data as *mut _);
186 }
187 }
188 let destroy_call4 = Some(destroy_func::<P> as _);
189 let super_callback0: Box_<P> = log_func_data;
190 unsafe {
191 from_glib(ffi::g_log_set_handler_full(
192 log_domain.to_glib_none().0,
193 log_levels.into_glib() | to_log_flags(fatal, recursion),
194 log_func,
195 Box_::into_raw(super_callback0) as *mut _,
196 destroy_call4,
197 ))
198 }
199}
200
201#[doc(alias = "g_log_remove_handler")]
202pub fn log_remove_handler(log_domain: Option<&str>, handler_id: LogHandlerId) {
203 unsafe {
204 ffi::g_log_remove_handler(log_domain.to_glib_none().0, handler_id.into_glib());
205 }
206}
207
208#[doc(alias = "g_log_set_always_fatal")]
209pub fn log_set_always_fatal(fatal_levels: LogLevels) -> LogLevels {
210 unsafe { from_glib(ffi::g_log_set_always_fatal(fatal_levels.into_glib())) }
211}
212
213#[doc(alias = "g_log_set_fatal_mask")]
214pub fn log_set_fatal_mask(log_domain: Option<&str>, fatal_levels: LogLevels) -> LogLevels {
215 unsafe {
216 from_glib(ffi::g_log_set_fatal_mask(
217 log_domain.to_glib_none().0,
218 fatal_levels.into_glib(),
219 ))
220 }
221}
222
223type PrintCallback = dyn Fn(&str) + Send + Sync + 'static;
224
225fn print_handler() -> &'static Mutex<Option<Arc<PrintCallback>>> {
226 static MUTEX: OnceLock<Mutex<Option<Arc<PrintCallback>>>> = OnceLock::new();
227 MUTEX.get_or_init(|| Mutex::new(None))
228}
229
230#[doc(alias = "g_set_print_handler")]
233pub fn set_print_handler<P: Fn(&str) + Send + Sync + 'static>(func: P) {
234 unsafe extern "C" fn func_func(string: *const libc::c_char) {
235 unsafe {
236 if let Some(callback) = print_handler()
237 .lock()
238 .expect("Failed to lock PRINT_HANDLER")
239 .as_ref()
240 .map(Arc::clone)
241 {
242 let string: Borrowed<GString> = from_glib_borrow(string);
243 (*callback)(string.as_str())
244 }
245 }
246 }
247 *print_handler()
248 .lock()
249 .expect("Failed to lock PRINT_HANDLER to change callback") = Some(Arc::new(func));
250 unsafe { ffi::g_set_print_handler(Some(func_func as _)) };
251}
252
253pub fn unset_print_handler() {
256 *print_handler()
257 .lock()
258 .expect("Failed to lock PRINT_HANDLER to remove callback") = None;
259 unsafe { ffi::g_set_print_handler(None) };
260}
261
262fn printerr_handler() -> &'static Mutex<Option<Arc<PrintCallback>>> {
263 static MUTEX: OnceLock<Mutex<Option<Arc<PrintCallback>>>> = OnceLock::new();
264 MUTEX.get_or_init(|| Mutex::new(None))
265}
266
267#[doc(alias = "g_set_printerr_handler")]
270pub fn set_printerr_handler<P: Fn(&str) + Send + Sync + 'static>(func: P) {
271 unsafe extern "C" fn func_func(string: *const libc::c_char) {
272 unsafe {
273 if let Some(callback) = printerr_handler()
274 .lock()
275 .expect("Failed to lock PRINTERR_HANDLER")
276 .as_ref()
277 .map(Arc::clone)
278 {
279 let string: Borrowed<GString> = from_glib_borrow(string);
280 (*callback)(string.as_str())
281 }
282 }
283 }
284 *printerr_handler()
285 .lock()
286 .expect("Failed to lock PRINTERR_HANDLER to change callback") = Some(Arc::new(func));
287 unsafe { ffi::g_set_printerr_handler(Some(func_func as _)) };
288}
289
290pub fn unset_printerr_handler() {
293 *printerr_handler()
294 .lock()
295 .expect("Failed to lock PRINTERR_HANDLER to remove callback") = None;
296 unsafe { ffi::g_set_printerr_handler(None) };
297}
298
299type LogCallback = dyn Fn(Option<&str>, LogLevel, &str) + Send + Sync + 'static;
300
301fn default_handler() -> &'static Mutex<Option<Arc<LogCallback>>> {
302 static MUTEX: OnceLock<Mutex<Option<Arc<LogCallback>>>> = OnceLock::new();
303 MUTEX.get_or_init(|| Mutex::new(None))
304}
305
306#[doc(alias = "g_log_set_default_handler")]
309pub fn log_set_default_handler<P: Fn(Option<&str>, LogLevel, &str) + Send + Sync + 'static>(
310 log_func: P,
311) {
312 unsafe extern "C" fn func_func(
313 log_domain: *const libc::c_char,
314 log_levels: ffi::GLogLevelFlags,
315 message: *const libc::c_char,
316 _user_data: ffi::gpointer,
317 ) {
318 unsafe {
319 if let Some(callback) = default_handler()
320 .lock()
321 .expect("Failed to lock DEFAULT_HANDLER")
322 .as_ref()
323 .map(Arc::clone)
324 {
325 let log_domain: Borrowed<Option<GString>> = from_glib_borrow(log_domain);
326 let message: Borrowed<GString> = from_glib_borrow(message);
327 (*callback)(
328 (*log_domain).as_ref().map(|s| s.as_str()),
329 from_glib(log_levels),
330 message.as_str(),
331 );
332 }
333 }
334 }
335 *default_handler()
336 .lock()
337 .expect("Failed to lock DEFAULT_HANDLER to change callback") = Some(Arc::new(log_func));
338 unsafe { ffi::g_log_set_default_handler(Some(func_func as _), std::ptr::null_mut()) };
339}
340
341#[doc(alias = "g_log_set_default_handler")]
344pub fn log_unset_default_handler() {
345 *default_handler()
346 .lock()
347 .expect("Failed to lock DEFAULT_HANDLER to remove callback") = None;
348 unsafe {
349 ffi::g_log_set_default_handler(Some(ffi::g_log_default_handler), std::ptr::null_mut())
350 };
351}
352
353#[doc(alias = "g_log_default_handler")]
354pub fn log_default_handler(log_domain: Option<&str>, log_level: LogLevel, message: Option<&str>) {
355 unsafe {
356 ffi::g_log_default_handler(
357 log_domain.to_glib_none().0,
358 log_level.into_glib(),
359 message.to_glib_none().0,
360 std::ptr::null_mut(),
361 )
362 }
363}
364
365#[repr(transparent)]
373#[derive(Debug)]
374#[doc(alias = "GLogField")]
375pub struct LogField<'a>(ffi::GLogField, std::marker::PhantomData<&'a GStr>);
376
377impl<'a> LogField<'a> {
378 pub fn new(key: &'a GStr, value: &'a [u8]) -> Self {
384 let (value, length) = if value.is_empty() {
385 (&[0u8] as &[u8], -1isize)
388 } else {
389 (value, value.len().try_into().unwrap())
390 };
391 Self(
392 ffi::GLogField {
393 key: key.as_ptr(),
394 value: value.as_ptr() as *const _,
395 length,
396 },
397 Default::default(),
398 )
399 }
400 pub fn new_user_data(key: &'a GStr, data: usize) -> Self {
410 Self(
411 ffi::GLogField {
412 key: key.as_ptr(),
413 value: std::ptr::without_provenance(data),
414 length: 0,
415 },
416 Default::default(),
417 )
418 }
419 pub fn key(&self) -> &str {
422 unsafe { std::ffi::CStr::from_ptr(self.0.key as *const _) }
423 .to_str()
424 .unwrap()
425 }
426 pub fn value_bytes(&self) -> Option<&[u8]> {
430 match self.0.length {
431 0 => None,
432 n if n < 0 => {
433 Some(unsafe { std::ffi::CStr::from_ptr(self.0.value as *const _) }.to_bytes())
434 }
435 _ => Some(unsafe {
436 std::slice::from_raw_parts(self.0.value as *const u8, self.0.length as usize)
437 }),
438 }
439 }
440 pub fn value_str(&self) -> Option<&str> {
444 std::str::from_utf8(self.value_bytes()?).ok()
445 }
446 pub fn user_data(&self) -> Option<usize> {
450 (self.0.length == 0).then_some(self.0.value.addr())
451 }
452}
453
454type WriterCallback = dyn Fn(LogLevel, &[LogField<'_>]) -> LogWriterOutput + Send + Sync + 'static;
455
456static WRITER_FUNC: OnceLock<Box<WriterCallback>> = OnceLock::new();
457
458#[doc(alias = "g_log_set_writer_func")]
459pub fn log_set_writer_func<
460 P: Fn(LogLevel, &[LogField<'_>]) -> LogWriterOutput + Send + Sync + 'static,
461>(
462 writer_func: P,
463) {
464 if WRITER_FUNC.set(Box::new(writer_func)).is_err() {
465 panic!("Writer func can only be set once");
466 }
467 unsafe extern "C" fn writer_trampoline(
468 log_level: ffi::GLogLevelFlags,
469 fields: *const ffi::GLogField,
470 n_fields: libc::size_t,
471 _user_data: ffi::gpointer,
472 ) -> ffi::GLogWriterOutput {
473 unsafe {
474 let writer_func = WRITER_FUNC.get().unwrap();
475 let fields = std::slice::from_raw_parts(fields as *const LogField<'_>, n_fields);
476 writer_func(from_glib(log_level), fields).into_glib()
477 }
478 }
479 unsafe {
480 ffi::g_log_set_writer_func(Some(writer_trampoline), std::ptr::null_mut(), None);
481 }
482}
483
484#[macro_export]
485#[doc(hidden)]
486macro_rules! g_log_inner {
487 ($log_domain:expr, $log_level:expr, $format:literal $(,$arg:expr)* $(,)?) => {{
488 let mut w = $crate::GStringBuilder::default();
489
490 if !std::fmt::Write::write_fmt(&mut w, std::format_args!($format, $($arg),*)).is_err() {
492 unsafe {
493 $crate::ffi::g_log(
494 $crate::translate::ToGlibPtr::to_glib_none(&$log_domain).0,
495 <$crate::LogLevel as $crate::translate::IntoGlib>::into_glib(
496 $log_level
497 ),
498 b"%s\0".as_ptr() as *const _,
499 $crate::translate::ToGlibPtr::<*const std::os::raw::c_char>::to_glib_none(
500 &w.into_string()
501 ).0,
502 );
503 }
504 }
505 }};
506}
507
508#[macro_export]
549macro_rules! g_log {
550 ($log_level:expr, $format:literal $(,$arg:expr)* $(,)?) => {{
551 $crate::g_log_inner!(None::<&str>, $log_level, $format, $($arg),*);
552 }};
553 ($log_domain:expr, $log_level:expr, $format:literal $(,$arg:expr)* $(,)?) => {{
554 let log_domain = <Option<&str> as std::convert::From<_>>::from($log_domain);
555 $crate::g_log_inner!(log_domain, $log_level, $format, $($arg),*);
556 }};
557}
558
559#[macro_export]
587macro_rules! g_error {
588 ($log_domain:expr, $format:literal, $($arg:expr),* $(,)?) => {{
589 $crate::g_log!($log_domain, $crate::LogLevel::Error, $format, $($arg),*);
590 }};
591 ($log_domain:expr, $format:literal $(,)?) => {{
592 $crate::g_log!($log_domain, $crate::LogLevel::Error, $format);
593 }};
594}
595
596#[macro_export]
624macro_rules! g_critical {
625 ($log_domain:expr, $format:literal, $($arg:expr),* $(,)?) => {{
626 $crate::g_log!($log_domain, $crate::LogLevel::Critical, $format, $($arg),*);
627 }};
628 ($log_domain:expr, $format:literal $(,)?) => {{
629 $crate::g_log!($log_domain, $crate::LogLevel::Critical, $format);
630 }};
631}
632
633#[macro_export]
661macro_rules! g_warning {
662 ($log_domain:expr, $format:literal, $($arg:expr),* $(,)?) => {{
663 $crate::g_log!($log_domain, $crate::LogLevel::Warning, $format, $($arg),*);
664 }};
665 ($log_domain:expr, $format:literal $(,)?) => {{
666 $crate::g_log!($log_domain, $crate::LogLevel::Warning, $format);
667 }};
668}
669
670#[macro_export]
698macro_rules! g_message {
699 ($log_domain:expr, $format:literal, $($arg:expr),* $(,)?) => {{
700 $crate::g_log!($log_domain, $crate::LogLevel::Message, $format, $($arg),*);
701 }};
702 ($log_domain:expr, $format:literal $(,)?) => {{
703 $crate::g_log!($log_domain, $crate::LogLevel::Message, $format);
704 }};
705}
706
707#[macro_export]
735macro_rules! g_info {
736 ($log_domain:expr, $format:literal, $($arg:expr),* $(,)?) => {{
737 $crate::g_log!($log_domain, $crate::LogLevel::Info, $format, $($arg),*);
738 }};
739 ($log_domain:expr, $format:literal $(,)?) => {{
740 $crate::g_log!($log_domain, $crate::LogLevel::Info, $format);
741 }};
742}
743
744#[macro_export]
772macro_rules! g_debug {
773 ($log_domain:expr, $format:literal, $($arg:expr),* $(,)?) => {{
774 $crate::g_log!($log_domain, $crate::LogLevel::Debug, $format, $($arg),*);
775 }};
776 ($log_domain:expr, $format:literal $(,)?) => {{
777 $crate::g_log!($log_domain, $crate::LogLevel::Debug, $format);
778 }};
779}
780
781#[doc(hidden)]
782#[macro_export]
783macro_rules! g_print_inner {
784 ($func:ident, $format:expr $(, $arg:expr)* $(,)?) => {{
785 let mut w = $crate::GStringBuilder::default();
786
787 if !std::fmt::Write::write_fmt(&mut w, std::format_args!($format, $($arg),*)).is_err() {
789 unsafe {
790 $crate::ffi::$func(
791 b"%s\0".as_ptr() as *const _,
792 $crate::translate::ToGlibPtr::<*const std::os::raw::c_char>::to_glib_none(
793 &w.into_string()
794 ).0,
795 );
796 }
797 }
798 }};
799}
800
801#[macro_export]
822macro_rules! g_print {
823 ($format:expr $(,$arg:expr)* $(,)?) => {{
824 $crate::g_print_inner!(g_print, $format, $($arg),*);
825 }};
826}
827
828#[macro_export]
849macro_rules! g_printerr {
850 ($format:expr $(, $arg:expr)* $(,)?) => {{
851 $crate::g_print_inner!(g_printerr, $format, $($arg),*);
852 }};
853}
854
855#[macro_export]
892macro_rules! log_structured {
893 ($log_domain:expr, $log_level:expr, {$($key:expr => $format:expr $(,$arg:expr)* $(,)?);+ $(;)?} $(,)?) => {{
894 let log_domain = <Option<&str> as std::convert::From<_>>::from($log_domain);
895 let log_domain_str = log_domain.unwrap_or_default();
896 let level: $crate::LogLevel = $log_level;
897 let field_count =
898 <[()]>::len(&[$($crate::log_structured_inner!(@clear $key)),+])
899 + log_domain.map(|_| 2usize).unwrap_or(1usize)
900 + 3;
901
902 let mut line = [0u8; 32]; let line = {
904 use std::io::Write;
905
906 let mut cursor = std::io::Cursor::new(&mut line[..]);
907 std::write!(&mut cursor, "{}", line!()).unwrap();
908 let pos = cursor.position() as usize;
909 &line[..pos]
910 };
911
912 $crate::log_structured_array(
913 level,
914 &[
915 $crate::LogField::new(
916 $crate::gstr!("PRIORITY"),
917 level.priority().as_bytes(),
918 ),
919 $crate::LogField::new(
920 $crate::gstr!("CODE_FILE"),
921 file!().as_bytes(),
922 ),
923 $crate::LogField::new(
924 $crate::gstr!("CODE_LINE"),
925 line,
926 ),
927 $crate::LogField::new(
928 $crate::gstr!("CODE_FUNC"),
929 $crate::function_name!().as_bytes(),
930 ),
931 $(
932 $crate::LogField::new(
933 $crate::log_structured_inner!(@key $key),
934 $crate::log_structured_inner!(@value $format $(,$arg)*),
935 ),
936 )+
937 $crate::LogField::new(
938 $crate::gstr!("GLIB_DOMAIN"),
939 log_domain_str.as_bytes(),
940 ),
941 ][0..field_count],
942 )
943 }};
944}
945
946#[doc(hidden)]
947#[macro_export]
948macro_rules! log_structured_inner {
949 (@clear $($_:tt)*) => { () };
950 (@key $key:literal) => { $crate::gstr!($key) };
951 (@key $key:expr) => { std::convert::AsRef::<$crate::GStr>::as_ref(&$key) };
952 (@value $value:expr) => { std::convert::AsRef::<[u8]>::as_ref(&$value) };
953 (@value $format:expr $(,$arg:expr)+) => {
954 {
955 let mut builder = $crate::GStringBuilder::default();
956 if std::fmt::Write::write_fmt(&mut builder, format_args!($format, $($arg),+)).is_err() {
957 return;
958 }
959 builder.into_string()
960 }.as_str().as_bytes()
961 };
962}
963
964#[doc(alias = "g_log_structured_array")]
965#[inline]
966pub fn log_structured_array(log_level: LogLevel, fields: &[LogField<'_>]) {
967 unsafe {
968 ffi::g_log_structured_array(
969 log_level.into_glib(),
970 fields.as_ptr() as *const ffi::GLogField,
971 fields.len(),
972 )
973 }
974}
975
976#[doc(alias = "g_log_variant")]
977#[inline]
978pub fn log_variant(log_domain: Option<&str>, log_level: LogLevel, fields: &crate::Variant) {
979 unsafe {
980 ffi::g_log_variant(
981 log_domain.to_glib_none().0,
982 log_level.into_glib(),
983 fields.to_glib_none().0,
984 );
985 }
986}
987
988#[cfg(unix)]
989#[cfg_attr(docsrs, doc(cfg(unix)))]
990#[doc(alias = "g_log_writer_supports_color")]
991#[inline]
992pub fn log_writer_supports_color(output_fd: impl AsFd) -> bool {
993 unsafe {
994 from_glib(ffi::g_log_writer_supports_color(
995 output_fd.as_fd().as_raw_fd(),
996 ))
997 }
998}
999
1000#[cfg(unix)]
1001#[cfg_attr(docsrs, doc(cfg(unix)))]
1002#[doc(alias = "g_log_writer_is_journald")]
1003#[inline]
1004pub fn log_writer_is_journald(output_fd: impl AsFd) -> bool {
1005 unsafe { from_glib(ffi::g_log_writer_is_journald(output_fd.as_fd().as_raw_fd())) }
1006}
1007
1008#[doc(alias = "g_log_writer_format_fields")]
1009#[inline]
1010pub fn log_writer_format_fields(
1011 log_level: LogLevel,
1012 fields: &[LogField<'_>],
1013 use_color: bool,
1014) -> GString {
1015 unsafe {
1016 from_glib_full(ffi::g_log_writer_format_fields(
1017 log_level.into_glib(),
1018 fields.as_ptr() as *const ffi::GLogField,
1019 fields.len(),
1020 use_color.into_glib(),
1021 ))
1022 }
1023}
1024
1025#[doc(alias = "g_log_writer_journald")]
1026#[inline]
1027pub fn log_writer_journald(log_level: LogLevel, fields: &[LogField<'_>]) -> LogWriterOutput {
1028 unsafe {
1029 from_glib(ffi::g_log_writer_journald(
1030 log_level.into_glib(),
1031 fields.as_ptr() as *const ffi::GLogField,
1032 fields.len(),
1033 std::ptr::null_mut(),
1034 ))
1035 }
1036}
1037
1038#[doc(alias = "g_log_writer_standard_streams")]
1039#[inline]
1040pub fn log_writer_standard_streams(
1041 log_level: LogLevel,
1042 fields: &[LogField<'_>],
1043) -> LogWriterOutput {
1044 unsafe {
1045 from_glib(ffi::g_log_writer_standard_streams(
1046 log_level.into_glib(),
1047 fields.as_ptr() as *const ffi::GLogField,
1048 fields.len(),
1049 std::ptr::null_mut(),
1050 ))
1051 }
1052}
1053
1054#[doc(alias = "g_log_writer_default")]
1055#[inline]
1056pub fn log_writer_default(log_level: LogLevel, fields: &[LogField<'_>]) -> LogWriterOutput {
1057 unsafe {
1058 from_glib(ffi::g_log_writer_default(
1059 log_level.into_glib(),
1060 fields.as_ptr() as *const ffi::GLogField,
1061 fields.len(),
1062 std::ptr::null_mut(),
1063 ))
1064 }
1065}
1066
1067#[cfg(feature = "v2_68")]
1078#[cfg_attr(docsrs, doc(cfg(feature = "v2_68")))]
1079#[doc(alias = "g_log_writer_default_set_use_stderr")]
1080#[inline]
1081pub unsafe fn log_writer_default_set_use_stderr(use_stderr: bool) {
1082 unsafe {
1083 ffi::g_log_writer_default_set_use_stderr(use_stderr.into_glib());
1084 }
1085}
1086
1087#[cfg(feature = "v2_68")]
1088#[cfg_attr(docsrs, doc(cfg(feature = "v2_68")))]
1089#[doc(alias = "g_log_writer_default_would_drop")]
1090#[inline]
1091pub fn log_writer_default_would_drop(log_level: LogLevel, log_domain: Option<&str>) -> bool {
1092 unsafe {
1093 from_glib(ffi::g_log_writer_default_would_drop(
1094 log_level.into_glib(),
1095 log_domain.to_glib_none().0,
1096 ))
1097 }
1098}
1099
1100#[cfg(feature = "v2_80")]
1101#[cfg_attr(docsrs, doc(cfg(feature = "v2_80")))]
1102#[doc(alias = "g_log_writer_default_set_debug_domains")]
1103#[inline]
1104pub fn log_writer_default_set_debug_domains(domains: &StrVRef) {
1105 unsafe { ffi::g_log_writer_default_set_debug_domains(domains.to_glib_none().0) }
1106}