apple_log/
os_signposter.rs1#![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, sanitized_c_string};
7use crate::error::LogError;
8use crate::ffi;
9use crate::logger::Logger;
10use crate::os_log::OSLog;
11use crate::os_signpost_id::OSSignpostId;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15pub struct OSSignpostInterval {
16 id: OSSignpostId,
17 animation: bool,
18}
19
20impl OSSignpostInterval {
21 #[must_use]
22 pub const fn id(self) -> OSSignpostId {
23 self.id
24 }
25
26 #[must_use]
27 pub const fn is_animation(self) -> bool {
28 self.animation
29 }
30}
31
32pub struct OSSignposter {
34 ptr: NonNull<c_void>,
35}
36
37impl OSSignposter {
38 fn bridge_default() -> Self {
39 Self {
40 ptr: NonNull::new(unsafe { ffi::apple_log_os_signposter_default() })
41 .expect("Swift bridge never returns NULL for OSSignposter.default"),
42 }
43 }
44
45 pub fn new(subsystem: &str, category: &str) -> Result<Self, LogError> {
51 let subsystem = c_string_arg("subsystem", subsystem)?;
52 let category = c_string_arg("category", category)?;
53 let ptr = bridge_ptr_result("OSSignposter::new", |error_out| unsafe {
54 ffi::apple_log_os_signposter_create(subsystem.as_ptr(), category.as_ptr(), error_out)
55 })?;
56 Ok(Self { ptr })
57 }
58
59 pub fn from_os_log(log: &OSLog) -> Result<Self, LogError> {
65 let ptr = bridge_ptr_result("OSSignposter::from_os_log", |error_out| unsafe {
66 ffi::apple_log_os_signposter_from_os_log(log.as_ptr(), error_out)
67 })?;
68 Ok(Self { ptr })
69 }
70
71 pub fn from_logger(logger: &Logger) -> Result<Self, LogError> {
77 let ptr = bridge_ptr_result("OSSignposter::from_logger", |error_out| unsafe {
78 ffi::apple_log_os_signposter_from_logger(logger.as_ptr(), error_out)
79 })?;
80 Ok(Self { ptr })
81 }
82
83 #[must_use]
84 pub fn default() -> Self {
85 Self::bridge_default()
86 }
87
88 #[must_use]
89 pub fn disabled() -> Self {
90 Self {
91 ptr: NonNull::new(unsafe { ffi::apple_log_os_signposter_disabled() })
92 .expect("Swift bridge never returns NULL for OSSignposter.disabled"),
93 }
94 }
95
96 #[must_use]
97 pub fn is_enabled(&self) -> bool {
98 unsafe { ffi::apple_log_os_signposter_is_enabled(self.ptr.as_ptr()) }
99 }
100
101 #[must_use]
102 pub fn make_signpost_id(&self) -> OSSignpostId {
103 OSSignpostId::from_u64(unsafe { ffi::apple_log_os_signposter_make_signpost_id(self.ptr.as_ptr()) })
104 }
105
106 #[must_use]
107 pub fn make_signpost_id_from_pointer<T>(&self, pointer: *const T) -> OSSignpostId {
108 OSSignpostId::from_u64(unsafe {
109 ffi::apple_log_os_signposter_make_signpost_id_from_pointer(self.ptr.as_ptr(), pointer.cast())
110 })
111 }
112
113 pub fn emit_event(&self, name: &str, id: OSSignpostId, message: &str) {
114 let name = sanitized_c_string(name);
115 let message = sanitized_c_string(message);
116 unsafe {
117 ffi::apple_log_os_signposter_emit_event(
118 self.ptr.as_ptr(),
119 id.as_u64(),
120 name.as_ptr(),
121 message.as_ptr(),
122 );
123 }
124 }
125
126 #[must_use]
127 pub fn begin_interval(&self, name: &str, id: OSSignpostId, message: &str) -> OSSignpostInterval {
128 let name = sanitized_c_string(name);
129 let message = sanitized_c_string(message);
130 unsafe {
131 ffi::apple_log_os_signposter_begin_interval(
132 self.ptr.as_ptr(),
133 id.as_u64(),
134 name.as_ptr(),
135 message.as_ptr(),
136 );
137 }
138 OSSignpostInterval { id, animation: false }
139 }
140
141 #[must_use]
142 pub fn begin_animation_interval(
143 &self,
144 name: &str,
145 id: OSSignpostId,
146 message: &str,
147 ) -> OSSignpostInterval {
148 let name = sanitized_c_string(name);
149 let message = sanitized_c_string(message);
150 unsafe {
151 ffi::apple_log_os_signposter_begin_animation_interval(
152 self.ptr.as_ptr(),
153 id.as_u64(),
154 name.as_ptr(),
155 message.as_ptr(),
156 );
157 }
158 OSSignpostInterval { id, animation: true }
159 }
160
161 pub fn end_interval(&self, name: &str, interval: OSSignpostInterval, message: &str) {
162 let name = sanitized_c_string(name);
163 let message = sanitized_c_string(message);
164 unsafe {
165 ffi::apple_log_os_signposter_end_interval(
166 self.ptr.as_ptr(),
167 interval.id.as_u64(),
168 name.as_ptr(),
169 message.as_ptr(),
170 );
171 }
172 }
173
174 pub fn with_interval_signpost<T>(
175 &self,
176 name: &str,
177 id: OSSignpostId,
178 message: &str,
179 around: impl FnOnce() -> T,
180 ) -> T {
181 let interval = self.begin_interval(name, id, message);
182 let result = around();
183 self.end_interval(name, interval, message);
184 result
185 }
186}
187
188impl Default for OSSignposter {
189 fn default() -> Self {
190 Self::bridge_default()
191 }
192}
193
194impl Drop for OSSignposter {
195 fn drop(&mut self) {
196 unsafe { ffi::apple_log_os_signposter_release(self.ptr.as_ptr()) };
197 }
198}