[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