1#![allow(clippy::missing_panics_doc, clippy::should_implement_trait)]
2
3use core::ffi::c_void;
4use std::ptr::NonNull;
5
6use crate::bridge_support::{bridge_ptr_result, c_string_arg, take_optional_c_string};
7use crate::error::LogError;
8use crate::ffi;
9
10pub const CATEGORY_POINTS_OF_INTEREST: &str = ffi::category::POINTS_OF_INTEREST;
11pub const CATEGORY_DYNAMIC_TRACING: &str = ffi::category::DYNAMIC_TRACING;
12pub const CATEGORY_DYNAMIC_STACK_TRACING: &str = ffi::category::DYNAMIC_STACK_TRACING;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16#[repr(u8)]
17pub enum Level {
18 Default = ffi::level::DEFAULT,
19 Info = ffi::level::INFO,
20 Debug = ffi::level::DEBUG,
21 Error = ffi::level::ERROR,
22 Fault = ffi::level::FAULT,
23}
24
25pub struct OSLog {
27 ptr: NonNull<c_void>,
28}
29
30impl OSLog {
31 fn bridge_default() -> Self {
32 Self {
33 ptr: NonNull::new(unsafe { ffi::apple_log_os_log_default() })
34 .expect("Swift bridge never returns NULL for OSLog.default"),
35 }
36 }
37
38 pub fn new(subsystem: &str, category: &str) -> Result<Self, LogError> {
44 let subsystem = c_string_arg("subsystem", subsystem)?;
45 let category = c_string_arg("category", category)?;
46 let ptr = bridge_ptr_result("OSLog::new", |error_out| unsafe {
47 ffi::apple_log_os_log_create(subsystem.as_ptr(), category.as_ptr(), error_out)
48 })?;
49 Ok(Self { ptr })
50 }
51
52 #[must_use]
54 pub fn default() -> Self {
55 Self::bridge_default()
56 }
57
58 #[must_use]
60 pub fn disabled() -> Self {
61 Self {
62 ptr: NonNull::new(unsafe { ffi::apple_log_os_log_disabled() })
63 .expect("Swift bridge never returns NULL for OSLog.disabled"),
64 }
65 }
66
67 #[must_use]
69 pub fn is_enabled(&self, level: Level) -> bool {
70 unsafe { ffi::apple_log_os_log_is_enabled(self.ptr.as_ptr(), level as u8) }
71 }
72
73 #[must_use]
75 pub fn signposts_enabled(&self) -> bool {
76 unsafe { ffi::apple_log_os_log_signposts_enabled(self.ptr.as_ptr()) }
77 }
78
79 #[must_use]
81 pub fn subsystem(&self) -> Option<String> {
82 unsafe { take_optional_c_string(ffi::apple_log_os_log_copy_subsystem(self.ptr.as_ptr())) }
83 }
84
85 #[must_use]
87 pub fn category(&self) -> Option<String> {
88 unsafe { take_optional_c_string(ffi::apple_log_os_log_copy_category(self.ptr.as_ptr())) }
89 }
90
91 pub(crate) const fn as_ptr(&self) -> *mut c_void {
92 self.ptr.as_ptr()
93 }
94}
95
96impl Default for OSLog {
97 fn default() -> Self {
98 Self::bridge_default()
99 }
100}
101
102impl Drop for OSLog {
103 fn drop(&mut self) {
104 unsafe { ffi::apple_log_os_log_release(self.ptr.as_ptr()) };
105 }
106}