[vlc-commits] [Git][videolan/vlc][master] 4 commits: rust: add vlc_messages.h to vlcrs-sys-generator

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Mon Aug 28 18:18:51 UTC 2023



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
d84f0c04 by Loïc Branstett at 2023-08-28T18:05:36+00:00
rust: add vlc_messages.h to vlcrs-sys-generator

- - - - -
33f2f0a2 by Loïc Branstett at 2023-08-28T18:05:36+00:00
rust: generate sys for vlcrs-messages

- - - - -
28957228 by Loïc Branstett at 2023-08-28T18:05:36+00:00
rust: add utility crate for usage by other rust crates

- - - - -
25b39a43 by Loïc Branstett at 2023-08-28T18:05:36+00:00
rust: add abstraction for vlc_Logger in vlcrs-messages

This patch adds abstraction for vlc_Logger, via the Rust Logger type and
similar macros as the C side with: debug!, info!, warn! and error!.

- - - - -


7 changed files:

- src/rust/Cargo.toml
- + src/rust/vlcrs-messages/Cargo.toml
- + src/rust/vlcrs-messages/src/lib.rs
- + src/rust/vlcrs-messages/src/sys.rs
- src/rust/vlcrs-sys-generator/src/main.rs
- + src/rust/vlcrs-utils/Cargo.toml
- + src/rust/vlcrs-utils/src/lib.rs


Changes:

=====================================
src/rust/Cargo.toml
=====================================
@@ -1,4 +1,5 @@
 [workspace]
 members = [
+    "vlcrs-messages",
     "vlcrs-sys-generator"
 ]


=====================================
src/rust/vlcrs-messages/Cargo.toml
=====================================
@@ -0,0 +1,8 @@
+[package]
+name = "vlcrs-messages"
+version = "0.0.0"
+edition = "2021"
+license = "LGPL-2.1-or-later"
+
+[dependencies]
+vlcrs-utils = { path = "../vlcrs-utils" }


=====================================
src/rust/vlcrs-messages/src/lib.rs
=====================================
@@ -0,0 +1,138 @@
+//! Messages facilities.
+
+use std::{ffi::CStr, ptr::NonNull};
+
+mod sys;
+use sys::{vlc_Log, vlc_logger};
+
+pub use sys::vlc_log_type as LogType;
+
+/// Logger object to be used with the warn!, error!, log! macros
+#[repr(transparent)]
+pub struct Logger(pub(crate) NonNull<vlc_logger>);
+
+impl Logger {
+    /// Log message to the logger
+    pub fn log(
+        &self,
+        priority: LogType,
+        logger: &CStr,
+        file: &CStr,
+        func: &CStr,
+        line: u32,
+        msg: &str,
+    ) {
+        const GENERIC: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"generic\0") };
+        const PRINTF_S: &CStr = unsafe { CStr::from_bytes_with_nul_unchecked(b"%.*s\0") };
+
+        // SAFETY: All the pointers are non-null and points to initialized structs.
+        unsafe {
+            vlc_Log(
+                &self.0.as_ptr(),
+                priority as i32,
+                GENERIC.as_ptr(),
+                logger.as_ptr(),
+                file.as_ptr(),
+                line,
+                func.as_ptr(),
+                // We do this to avoid manipulating the original formatted string to be printf
+                // escaped. Using %s is just way simpler.
+                PRINTF_S.as_ptr(),
+                msg.len(),
+                msg.as_ptr(),
+            )
+        }
+    }
+}
+
+/// Log for a VLC Object
+#[macro_export]
+macro_rules! log {
+    ($logger:expr, $level:expr, $format:expr, $($args:expr),*) => {{
+        // SAFETY: The file name cannot be nul and doens't contains nul byte.
+        // With the concat of the nul byte the slice is now a C-style array.
+        let file = unsafe { ::std::ffi::CStr::from_bytes_with_nul_unchecked(concat!(file!(), "\0").as_bytes()) };
+        let func = ::std::ffi::CString::new(::vlcrs_utils::func!())
+            .expect("should always be valid utf-8");
+        let logger = ::std::ffi::CString::new(option_env!("VLC_logger_NAME").unwrap_or("<unknown rust logger>"))
+            .expect("unable to create the rust module name");
+        let formatted = ::std::fmt::format(format_args!("{}\0", format_args!($format, $($args),*)));
+        ::vlcrs_messages::Logger::log(
+            $logger,
+            $level,
+            logger.as_c_str(),
+            file,
+            func.as_c_str(),
+            line!(),
+            &formatted
+        )
+    }};
+}
+
+/// Debug-level log for a VLC Object
+///
+/// ```ignore
+/// // let logger = ...;
+/// vlcrs_messages::debug!(logger, "test");
+/// ```
+#[macro_export]
+#[doc(alias = "msg_Dbg")]
+macro_rules! debug {
+    ($logger:expr, $format:expr $(,)?) => {{
+        $crate::log!($logger, $crate::LogType::VLC_MSG_DBG, $format,)
+    }};
+    ($logger:expr, $format:expr, $($args:tt)*) => {{
+        $crate::log!($logger, $crate::LogType::VLC_MSG_DBG, $format, $($args)*)
+    }};
+}
+
+/// Info-level log for a VLC Object
+///
+/// ```ignore
+/// // let logger = ...;
+/// vlcrs_messages::info!(logger, "test");
+/// ```
+#[macro_export]
+#[doc(alias = "msg_Err")]
+macro_rules! info {
+    ($logger:expr, $format:expr $(,)?) => {{
+        $crate::log!($logger, $crate::LogType::VLC_MSG_INFO, $format,)
+    }};
+    ($logger:expr, $format:expr, $($args:tt)*) => {{
+        $crate::log!($logger, $crate::LogType::VLC_MSG_INFO, $format, $($args)*)
+    }};
+}
+
+/// Warning-level log for a VLC Object
+///
+/// ```ignore
+/// // let logger = ...;
+/// vlcrs_messages::warn!(logger, "test");
+/// ```
+#[macro_export]
+#[doc(alias = "msg_Warn")]
+macro_rules! warn {
+    ($logger:expr, $format:expr $(,)?) => {{
+        $crate::log!($logger, $crate::LogType::VLC_MSG_WARN, $format,)
+    }};
+    ($logger:expr, $format:expr, $($args:tt)*) => {{
+        $crate::log!($logger, $crate::LogType::VLC_MSG_WARN, $format, $($args)*)
+    }};
+}
+
+/// Error-level log for a VLC Object
+///
+/// ```ignore
+/// // let logger = ...;
+/// vlcrs_messages::error!(logger, "test");
+/// ```
+#[macro_export]
+#[doc(alias = "msg_Err")]
+macro_rules! error {
+    ($logger:expr, $format:expr $(,)?) => {{
+        $crate::log!($logger, $crate::LogType::VLC_MSG_ERR, $format,)
+    }};
+    ($logger:expr, $format:expr, $($args:tt)*) => {{
+        $crate::log!($logger, $crate::LogType::VLC_MSG_ERR, $format, $($args)*)
+    }};
+}


=====================================
src/rust/vlcrs-messages/src/sys.rs
=====================================
@@ -0,0 +1,41 @@
+/* automatically generated by rust-bindgen 0.66.1 */
+
+#![allow(rustdoc::bare_urls)]
+#![allow(rustdoc::broken_intra_doc_links)]
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+
+#[repr(u32)]
+#[non_exhaustive]
+#[doc = " Message types"]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub enum vlc_log_type {
+    #[doc = "< Important information"]
+    VLC_MSG_INFO = 0,
+    #[doc = "< Error"]
+    VLC_MSG_ERR = 1,
+    #[doc = "< Warning"]
+    VLC_MSG_WARN = 2,
+    #[doc = "< Debug"]
+    VLC_MSG_DBG = 3,
+}
+#[doc = " \\defgroup logger Logger\n \\brief Message log back-end.\n\n @{"]
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct vlc_logger {
+    _unused: [u8; 0],
+}
+extern "C" {
+    pub fn vlc_Log(
+        logger: *const *mut vlc_logger,
+        prio: ::std::os::raw::c_int,
+        type_: *const ::std::os::raw::c_char,
+        module: *const ::std::os::raw::c_char,
+        file: *const ::std::os::raw::c_char,
+        line: ::std::os::raw::c_uint,
+        func: *const ::std::os::raw::c_char,
+        format: *const ::std::os::raw::c_char,
+        ...
+    );
+}


=====================================
src/rust/vlcrs-sys-generator/src/main.rs
=====================================
@@ -81,8 +81,17 @@ impl BindingsGenerator {
 }
 
 fn main() {
-    #[allow(unused)]
     let bindings_gen = BindingsGenerator {
         include_path: env::var("INCLUDE_PATH").unwrap_or_else(|_| "../../include".to_string()),
     };
+
+    bindings_gen.generate_bindings_for("vlcrs-messages", &["vlc_messages.h"], |builder| {
+        builder
+            .allowlist_function("vlc_Log")
+            .allowlist_type("vlc_logger")
+            .allowlist_type("vlc_log_type")
+            .default_enum_style(bindgen::EnumVariation::Rust {
+                non_exhaustive: true,
+            })
+    });
 }


=====================================
src/rust/vlcrs-utils/Cargo.toml
=====================================
@@ -0,0 +1,7 @@
+[package]
+name = "vlcrs-utils"
+version = "0.0.0"
+edition = "2021"
+license = "LGPL-2.1-or-later"
+
+[dependencies]


=====================================
src/rust/vlcrs-utils/src/lib.rs
=====================================
@@ -0,0 +1,23 @@
+//! Utilities functions for vlcrs crates
+
+/// Function name getter.
+///
+/// This macro returns the name of the enclosing function.
+/// As the internal implementation is based on the [`std::any::type_name`], this macro derives
+/// all the limitations of this function.
+//
+// Originate from stdext-rs (MIT-License: "Copyright (c) 2020 Igor Aleksanov"):
+//  - https://github.com/popzxc/stdext-rs/blob/a79153387aa3f08d08dcaff08e214a17851d61c4/src/macros.rs#L63-L74
+#[macro_export]
+macro_rules! func {
+    () => {{
+        // Okay, this is ugly, I get it. However, this is the best we can get on a stable rust.
+        fn f() {}
+        fn type_name_of<T>(_: T) -> &'static str {
+            std::any::type_name::<T>()
+        }
+        let name = type_name_of(f);
+        // `3` is the length of the `::f`.
+        &name[..name.len() - 3]
+    }};
+}



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/14798e65bf9bbb81e30e6120d7e990a910013327...25b39a43a5d336adea9960009ecb41dceaefa438

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/14798e65bf9bbb81e30e6120d7e990a910013327...25b39a43a5d336adea9960009ecb41dceaefa438
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list