pipewire_native_spa/interface/
log.rs

1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: Copyright (c) 2025 Asymptotic Inc.
3// SPDX-FileCopyrightText: Copyright (c) 2025 Arun Raghavan
4
5use std::{any::Any, ffi::CStr, pin::Pin};
6
7use pipewire_native_macros::EnumU32;
8
9use super::plugin::Interface;
10
11pub const LEVEL: &str = "log.level";
12pub const COLORS: &str = "log.colors";
13pub const FILE: &str = "log.file";
14pub const TIMESTAMP: &str = "log.timestamp";
15pub const LINE: &str = "log.line";
16pub const PATTERNS: &str = "log.patterns";
17
18#[repr(u32)]
19#[derive(Copy, Clone, Debug, EnumU32, PartialEq, Eq, PartialOrd, Ord)]
20pub enum LogLevel {
21    None = 0,
22    Error,
23    Warn,
24    Info,
25    Debug,
26    Trace,
27}
28
29impl TryFrom<&str> for LogLevel {
30    type Error = ();
31
32    fn try_from(value: &str) -> Result<Self, ()> {
33        match value {
34            "E" | "1" => Ok(LogLevel::Error),
35            "W" | "2" => Ok(LogLevel::Warn),
36            "I" | "3" => Ok(LogLevel::Info),
37            "D" | "4" => Ok(LogLevel::Debug),
38            "T" | "5" => Ok(LogLevel::Trace),
39            _ => Err(()),
40        }
41    }
42}
43
44#[derive(Debug)]
45pub struct LogTopic {
46    /* We use a CStr to make translation to C more efficient. We don't need this to be owned, as we
47     * expect to allocate it from global strings */
48    pub topic: &'static CStr,
49    pub level: LogLevel,
50    pub has_custom_level: bool,
51}
52
53/* TODO: need some macros to make logging less cumbersome */
54pub struct LogImpl {
55    pub inner: Pin<Box<dyn Any>>,
56    pub level: LogLevel,
57
58    pub log: fn(
59        this: &LogImpl,
60        level: LogLevel,
61        file: &CStr,
62        line: i32,
63        func: &CStr,
64        args: std::fmt::Arguments,
65    ),
66    pub logt: fn(
67        this: &LogImpl,
68        level: LogLevel,
69        topic: &LogTopic,
70        file: &CStr,
71        line: i32,
72        func: &CStr,
73        args: std::fmt::Arguments,
74    ),
75}
76
77impl LogImpl {
78    pub fn log(
79        &self,
80        level: LogLevel,
81        file: &CStr,
82        line: i32,
83        func: &CStr,
84        args: std::fmt::Arguments,
85    ) {
86        (self.log)(self, level, file, line, func, args)
87    }
88
89    pub fn logt(
90        &self,
91        level: LogLevel,
92        topic: &LogTopic,
93        file: &CStr,
94        line: i32,
95        func: &CStr,
96        args: std::fmt::Arguments,
97    ) {
98        (self.logt)(self, level, topic, file, line, func, args)
99    }
100}
101
102impl Interface for LogImpl {
103    unsafe fn make_native(&self) -> *mut super::ffi::CInterface {
104        crate::support::ffi::log::make_native(self)
105    }
106
107    unsafe fn free_native(log: *mut super::ffi::CInterface) {
108        crate::support::ffi::log::free_native(log)
109    }
110}