1 #![allow(non_camel_case_types)] 2 #![allow(dead_code)] 3 4 use std::{ffi::c_void, os::raw::c_char}; 5 6 #[repr(C)] 7 #[derive(Debug, Copy, Clone)] 8 pub struct os_log_s { 9 _unused: [u8; 0], 10 } 11 12 pub type os_log_t = *mut os_log_s; 13 pub type os_log_type_t = u8; 14 15 pub const OS_LOG_TYPE_DEFAULT: os_log_type_t = 0; 16 pub const OS_LOG_TYPE_INFO: os_log_type_t = 1; 17 pub const OS_LOG_TYPE_DEBUG: os_log_type_t = 2; 18 pub const OS_LOG_TYPE_ERROR: os_log_type_t = 16; 19 pub const OS_LOG_TYPE_FAULT: os_log_type_t = 17; 20 21 /// Provided by the OS. 22 extern "C" { os_log_create(subsystem: *const c_char, category: *const c_char) -> os_log_t23 pub fn os_log_create(subsystem: *const c_char, category: *const c_char) -> os_log_t; os_release(object: *mut c_void)24 pub fn os_release(object: *mut c_void); os_log_type_enabled(log: os_log_t, level: os_log_type_t) -> bool25 pub fn os_log_type_enabled(log: os_log_t, level: os_log_type_t) -> bool; 26 } 27 28 /// Wrappers defined in wrapper.c because most of the os_log_* APIs are macros. 29 extern "C" { wrapped_get_default_log() -> os_log_t30 pub fn wrapped_get_default_log() -> os_log_t; wrapped_os_log_with_type(log: os_log_t, log_type: os_log_type_t, message: *const c_char)31 pub fn wrapped_os_log_with_type(log: os_log_t, log_type: os_log_type_t, message: *const c_char); wrapped_os_log_debug(log: os_log_t, message: *const c_char)32 pub fn wrapped_os_log_debug(log: os_log_t, message: *const c_char); wrapped_os_log_info(log: os_log_t, message: *const c_char)33 pub fn wrapped_os_log_info(log: os_log_t, message: *const c_char); wrapped_os_log_default(log: os_log_t, message: *const c_char)34 pub fn wrapped_os_log_default(log: os_log_t, message: *const c_char); wrapped_os_log_error(log: os_log_t, message: *const c_char)35 pub fn wrapped_os_log_error(log: os_log_t, message: *const c_char); wrapped_os_log_fault(log: os_log_t, message: *const c_char)36 pub fn wrapped_os_log_fault(log: os_log_t, message: *const c_char); 37 } 38 39 #[cfg(test)] 40 mod tests { 41 use super::*; 42 use std::ffi::CString; 43 44 #[test] test_create_and_release()45 fn test_create_and_release() { 46 let subsystem = CString::new("com.example.test").unwrap(); 47 let category = CString::new("category").unwrap(); 48 let log = unsafe { os_log_create(subsystem.as_ptr(), category.as_ptr()) }; 49 assert!(!log.is_null()); 50 51 unsafe { 52 os_release(log as *mut _); 53 } 54 } 55 56 #[test] test_output_to_default_log()57 fn test_output_to_default_log() { 58 let message = CString::new("Hello!").unwrap(); 59 60 unsafe { 61 wrapped_os_log_debug(wrapped_get_default_log(), message.as_ptr()); 62 wrapped_os_log_info(wrapped_get_default_log(), message.as_ptr()); 63 wrapped_os_log_default(wrapped_get_default_log(), message.as_ptr()); 64 wrapped_os_log_error(wrapped_get_default_log(), message.as_ptr()); 65 wrapped_os_log_fault(wrapped_get_default_log(), message.as_ptr()); 66 67 wrapped_os_log_with_type( 68 wrapped_get_default_log(), 69 OS_LOG_TYPE_DEBUG, 70 message.as_ptr(), 71 ); 72 wrapped_os_log_with_type( 73 wrapped_get_default_log(), 74 OS_LOG_TYPE_INFO, 75 message.as_ptr(), 76 ); 77 wrapped_os_log_with_type( 78 wrapped_get_default_log(), 79 OS_LOG_TYPE_DEFAULT, 80 message.as_ptr(), 81 ); 82 wrapped_os_log_with_type( 83 wrapped_get_default_log(), 84 OS_LOG_TYPE_ERROR, 85 message.as_ptr(), 86 ); 87 wrapped_os_log_with_type( 88 wrapped_get_default_log(), 89 OS_LOG_TYPE_FAULT, 90 message.as_ptr(), 91 ); 92 } 93 } 94 95 #[test] test_output_to_custom_log()96 fn test_output_to_custom_log() { 97 let subsystem = CString::new("com.example.test").unwrap(); 98 let category = CString::new("category").unwrap(); 99 let log = unsafe { os_log_create(subsystem.as_ptr(), category.as_ptr()) }; 100 let message = CString::new("Hello!").unwrap(); 101 102 unsafe { 103 wrapped_os_log_debug(log, message.as_ptr()); 104 wrapped_os_log_info(log, message.as_ptr()); 105 wrapped_os_log_default(log, message.as_ptr()); 106 wrapped_os_log_error(log, message.as_ptr()); 107 wrapped_os_log_fault(log, message.as_ptr()); 108 109 wrapped_os_log_with_type(log, OS_LOG_TYPE_DEBUG, message.as_ptr()); 110 wrapped_os_log_with_type(log, OS_LOG_TYPE_INFO, message.as_ptr()); 111 wrapped_os_log_with_type(log, OS_LOG_TYPE_DEFAULT, message.as_ptr()); 112 wrapped_os_log_with_type(log, OS_LOG_TYPE_ERROR, message.as_ptr()); 113 wrapped_os_log_with_type(log, OS_LOG_TYPE_FAULT, message.as_ptr()); 114 115 os_release(log as *mut _); 116 } 117 } 118 } 119