From 1c2b5d4b5a0f9fc345d7f17284cf6d6a1b6b206b Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Fri, 26 Jun 2026 18:22:22 +0200 Subject: [PATCH] libutil: expose loggers to rust MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this takes the form of a couple of hideous macros for now to get started without worrying about semantics of rust logging and tracing crates, all of which are in some way incompatible with the current lix expectations. we do want to move to using those eventually, but that will have to be a task for later. as long as only small amounts of lix code live in crates we don't have to worry much anyway, and by the time we get around to any Activity beimg ported we'll hopefully have a better understanding of the requirements on either side. we'll reƫvaluate the log infra around then. Change-Id: I4aec476a486f56d0972294358cbf0b6810ab9394 --- lix/libutil/logging.cc | 23 +++++++++ lix/lix-rs/src/lib.rs | 113 +++++++++++++++++++++++++++++++++++++++++ lix/lix-rs/src/lib.zng | 8 +++ 3 files changed, 144 insertions(+) diff --git a/lix/libutil/logging.cc b/lix/libutil/logging.cc index b0b656908..38e7f92d9 100644 --- a/lix/libutil/logging.cc +++ b/lix/libutil/logging.cc @@ -1,4 +1,6 @@ #include "c-calls.hh" +#include "libutil/error.hh" +#include "lix-rs/utils.hh" #include "lix/libutil/config-impl.hh" #include "lix/libutil/environment-variables.hh" #include "lix/libutil/file-descriptor.hh" @@ -7,6 +9,7 @@ #include "lix/libutil/json.hh" #include "lix/libutil/position.hh" #include "lix/libutil/terminal.hh" +#include "main.gen.hh" #include "manually-drop.hh" #include @@ -138,9 +141,21 @@ public: Verbosity detail::verbosity = lvlInfo; +namespace { +struct InitRustVerbosity +{ + InitRustVerbosity(Verbosity v) + { + rust::lix::log::ffi::set_verbosity(v); + } +}; +static InitRustVerbosity _initRustVerbosity{detail::verbosity}; +} + void setVerbosity(Verbosity v) { detail::verbosity = v; + log::ffi::set_verbosity(v); } Verbosity verbosityFromIntClamped(int val) @@ -459,3 +474,11 @@ std::string LogLineSplitter::finish() return std::move(line); } } + +namespace rust::exported_functions { +Unit log_message(int lvl, Ref str) +{ + printMsg(nix::Verbosity(lvl), "%s", nix::Uncolored(to_std_string_view(str))); + return {}; +} +} diff --git a/lix/lix-rs/src/lib.rs b/lix/lix-rs/src/lib.rs index b1619ae55..f45ba2b79 100644 --- a/lix/lix-rs/src/lib.rs +++ b/lix/lix-rs/src/lib.rs @@ -32,4 +32,117 @@ mod ffi { impl error::Error for Error {} } +#[macro_use] +pub(crate) mod log { + use std::fmt::{Debug, Display}; + + static mut VERBOSITY: i32 = 99; + + // these MUST match the c++ struct exactly or log messages will be filtered incorrectly + #[allow(unused)] + pub const LVL_ERROR: i32 = 0; + #[allow(unused)] + pub const LVL_WARN: i32 = 1; + #[allow(unused)] + pub const LVL_NOTICE: i32 = 2; + #[allow(unused)] + pub const LVL_INFO: i32 = 3; + #[allow(unused)] + pub const LVL_TALKATIVE: i32 = 4; + #[allow(unused)] + pub const LVL_CHATTY: i32 = 5; + #[allow(unused)] + pub const LVL_DEBUG: i32 = 6; + #[allow(unused)] + pub const LVL_VOMIT: i32 = 7; + + pub struct Colorize(pub T); + + impl Display for Colorize { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("\x1b[35;1m")?; + Display::fmt(&self.0, f)?; + f.write_str("\x1b[0m") + } + } + + impl Debug for Colorize { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("\x1b[35;1m")?; + Debug::fmt(&self.0, f)?; + f.write_str("\x1b[0m") + } + } + + macro_rules! log_message { + ( __format plain: $e:expr ) => { + $e + }; + ( __format: $e:expr ) => { + crate::log::Colorize($e) + }; + ( $level:expr, $str:expr $(, $(plain)? $item:tt)* $(,)? ) => { + crate::generated::log_message( + $level, + &format!( + $str, + $( log_message!( __format: $item ) ),* + ) + ); + }; + } + + #[macro_export] + macro_rules! print_error { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_ERROR, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_warning { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_WARN, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_notice { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_NOTICE, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_info { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_INFO, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_talkative { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_TALKATIVE, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_chatty { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_CHATTY, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_debug { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_DEBUG, $str $($($rest)*)*) } + } + #[macro_export] + macro_rules! print_vomit { + ( $str:expr $(, $( $rest:tt )* )? ) => { log_message!(crate::log::LVL_VOMIT, $str $($($rest)*)*) } + } + + #[macro_export] + macro_rules! log_error { + ( $str:literal $($rest:tt)* ) => { + print_error!(concat!("\x1b[31;1merror:\x1b[0m ", $str), $($rest)*) + } + } + #[macro_export] + macro_rules! log_warning { + ( $str:literal $($rest:tt)* ) => { + print_warning!(concat!("\x1b[35;1mwarning:\x1b[0m ", $str), $($rest)*) + } + } + + pub(crate) mod ffi { + pub unsafe fn set_verbosity(level: i32) { + super::VERBOSITY = level; + } + } +} + mod ffi_test; diff --git a/lix/lix-rs/src/lib.zng b/lix/lix-rs/src/lib.zng index 7f1c6a4c3..3e163f92b 100644 --- a/lix/lix-rs/src/lib.zng +++ b/lix/lix-rs/src/lib.zng @@ -28,3 +28,11 @@ mod crate::ffi { #layout_conservative(size = 16, align = 8); } } + +mod crate::log::ffi { + fn set_verbosity(i32); + + extern "C++" { + safe fn log_message(i32, &str); + } +}