1use std::{
2 ffi::{CStr, CString},
3 io,
4};
5
6use libcamera_sys::*;
7
8use crate::utils::handle_result;
9
10#[derive(Copy, Clone, Debug)]
12pub enum LoggingTarget {
13 None,
14 Syslog,
15 File,
16 Stream,
17}
18
19impl From<LoggingTarget> for libcamera_logging_target_t {
20 fn from(value: LoggingTarget) -> Self {
21 match value {
22 LoggingTarget::None => libcamera_logging_target::LIBCAMERA_LOGGING_TARGET_NONE,
23 LoggingTarget::Syslog => libcamera_logging_target::LIBCAMERA_LOGGING_TARGET_SYSLOG,
24 LoggingTarget::File => libcamera_logging_target::LIBCAMERA_LOGGING_TARGET_FILE,
25 LoggingTarget::Stream => libcamera_logging_target::LIBCAMERA_LOGGING_TARGET_STREAM,
26 }
27 }
28}
29
30#[derive(Copy, Clone, Debug)]
31pub enum LoggingLevel {
32 Debug,
33 Info,
34 Warn,
35 Error,
36 Fatal,
37}
38
39impl From<LoggingLevel> for &'static CStr {
40 fn from(value: LoggingLevel) -> Self {
41 match value {
42 LoggingLevel::Debug => c"DEBUG",
43 LoggingLevel::Info => c"INFO",
44 LoggingLevel::Warn => c"WARN",
45 LoggingLevel::Error => c"ERROR",
46 LoggingLevel::Fatal => c"FATAL",
47 }
48 }
49}
50
51#[derive(Copy, Clone, Debug)]
52pub enum LoggingStream {
53 StdOut,
54 StdErr,
55 Custom(*mut core::ffi::c_void),
56}
57
58impl From<LoggingStream> for libcamera_logging_stream_t {
59 fn from(value: LoggingStream) -> Self {
60 match value {
61 LoggingStream::StdOut => libcamera_logging_stream::LIBCAMERA_LOGGING_STREAM_STDOUT,
62 LoggingStream::StdErr => libcamera_logging_stream::LIBCAMERA_LOGGING_STREAM_STDERR,
63 LoggingStream::Custom(_) => libcamera_logging_stream::LIBCAMERA_LOGGING_STREAM_CUSTOM,
64 }
65 }
66}
67
68pub fn log_set_file(file: &str, color: bool) -> io::Result<()> {
70 let file = CString::new(file).expect("file contains null byte");
71 let ret = unsafe { libcamera_log_set_file(file.as_ptr(), color) };
72 handle_result(ret)
73}
74
75pub fn log_set_stream(stream: LoggingStream, color: bool) -> io::Result<()> {
77 let ret = unsafe {
78 match stream {
79 LoggingStream::Custom(ptr) => libcamera_log_set_custom_stream(ptr, color),
80 _ => libcamera_log_set_stream(stream.into(), color),
81 }
82 };
83 handle_result(ret)
84}
85
86pub fn log_set_target(target: LoggingTarget) -> io::Result<()> {
88 let ret = unsafe { libcamera_log_set_target(target.into()) };
89 handle_result(ret)
90}
91
92pub fn configure_stderr(category: &str, level: LoggingLevel, color: bool) -> io::Result<()> {
94 log_set_stream(LoggingStream::StdErr, color)?;
95 let cm = crate::camera_manager::CameraManager::new()?;
96 cm.log_set_level(category, level);
97 Ok(())
98}
99
100pub fn configure_logging(target: LoggingTarget, stream: Option<LoggingStream>, color: bool) -> io::Result<()> {
102 if let Some(s) = stream {
103 log_set_stream(s, color)?;
104 log_set_target(LoggingTarget::Stream)?;
105 } else {
106 log_set_target(target)?;
107 }
108 Ok(())
109}
110
111pub fn configure_stdout(category: &str, level: LoggingLevel, color: bool) -> io::Result<()> {
113 log_set_stream(LoggingStream::StdOut, color)?;
114 set_category_level(category, level);
115 Ok(())
116}
117
118pub fn set_category_level(category: &str, level: LoggingLevel) {
120 let category = CString::new(category).expect("category contains null byte");
121 let level: &CStr = level.into();
122 unsafe { libcamera_log_set_level(category.as_ptr(), level.as_ptr()) };
123}