python interface for core and logging
cargo devel CI / cargo CI (push) Successful in 4m59s Details

This commit is contained in:
Christoph J. Scherr 2024-03-01 20:15:16 +01:00
parent e8be5388b1
commit 10ec77aef0
Signed by: PlexSheep
GPG Key ID: 7CDD0B14851A08EF
9 changed files with 130 additions and 44 deletions

View File

@ -12,7 +12,7 @@ default-members = [".", "members/libpt-core"]
[workspace.package] [workspace.package]
publish = true publish = true
version = "0.3.11" version = "0.3.12"
edition = "2021" edition = "2021"
authors = ["Christoph J. Scherr <software@cscherr.de>"] authors = ["Christoph J. Scherr <software@cscherr.de>"]
license = "MIT" license = "MIT"

View File

@ -1,21 +1,11 @@
//! # tools that make printing stuff better //! # tools that make printing stuff better
// reimport our macros to this module, so the user does not get confused when importing the macros
pub use crate::divider;
pub use crate::print_divider;
/// Quickly get a one line visual divider /// Quickly get a one line visual divider
#[macro_export] pub fn divider() -> String {
macro_rules! divider { format!("{:=^80}", "=")
() => {{
format!("{:=^80}", "=")
}};
} }
/// Quickly print a one line visual divider /// Quickly print a one line visual divider
#[macro_export] pub fn print_divider() {
macro_rules! print_divider { println!("{:=^80}", "=")
() => {{
println!("{}", divider!())
}};
} }

View File

@ -45,19 +45,13 @@ pub struct Logger;
/// ## Main implementation /// ## Main implementation
impl Logger { impl Logger {
/// ## create a `Logger`
///
/// Creates a new uninitialized [`Logger`] object.
pub fn new() -> Self {
Logger {}
}
/// ## initializes the logger /// ## initializes the logger
/// ///
/// Will enable the logger to be used. /// Will enable the logger to be used.
/// ///
/// Assumes some defaults, use [`init_customized`](Self::init_customized) for more control /// Assumes some defaults, use [`init_customized`](Self::init_customized) for more control
pub fn init(log_dir: Option<PathBuf>, max_level: Option<Level>, uptime: bool) -> Result<()> { pub fn build(log_dir: Option<PathBuf>, max_level: Option<Level>, uptime: bool) -> Result<Self> {
Self::init_customized( Self::build_customized(
log_dir.is_some(), log_dir.is_some(),
log_dir.unwrap_or(PathBuf::from(DEFAULT_LOG_DIR)), log_dir.unwrap_or(PathBuf::from(DEFAULT_LOG_DIR)),
true, true,
@ -80,8 +74,8 @@ impl Logger {
/// useful in cases with only one sender to the logging framework. /// useful in cases with only one sender to the logging framework.
/// ///
/// Assumes some defaults, use [`init_customized`](Self::init_customized) for more control /// Assumes some defaults, use [`init_customized`](Self::init_customized) for more control
pub fn init_mini(max_level: Option<Level>) -> Result<()> { pub fn build_mini(max_level: Option<Level>) -> Result<Self> {
Self::init_customized( Self::build_customized(
false, false,
PathBuf::from(DEFAULT_LOG_DIR), PathBuf::from(DEFAULT_LOG_DIR),
true, true,
@ -103,7 +97,7 @@ impl Logger {
/// ## initializes the logger /// ## initializes the logger
/// ///
/// Will enable the logger to be used. /// Will enable the logger to be used.
pub fn init_customized( pub fn build_customized(
log_to_file: bool, log_to_file: bool,
log_dir: PathBuf, log_dir: PathBuf,
ansi: bool, ansi: bool,
@ -117,7 +111,7 @@ impl Logger {
pretty: bool, pretty: bool,
show_time: bool, show_time: bool,
uptime: bool, // uptime instead of system time uptime: bool, // uptime instead of system time
) -> Result<()> { ) -> Result<Self> {
// only init if no init has been performed yet // only init if no init has been performed yet
if INITIALIZED.load(Ordering::Relaxed) { if INITIALIZED.load(Ordering::Relaxed) {
warn!("trying to reinitialize the logger, ignoring"); warn!("trying to reinitialize the logger, ignoring");
@ -205,7 +199,7 @@ impl Logger {
} }
} }
INITIALIZED.store(true, Ordering::Relaxed); INITIALIZED.store(true, Ordering::Relaxed);
Ok(()) Ok(Logger {})
} }
/// ## logging at [`Level::ERROR`] /// ## logging at [`Level::ERROR`]
@ -245,12 +239,6 @@ impl Logger {
} }
} }
impl Default for Logger {
fn default() -> Self {
Self::new()
}
}
impl fmt::Debug for Logger { impl fmt::Debug for Logger {
/// ## DEBUG representation for [`Logger`] /// ## DEBUG representation for [`Logger`]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

View File

@ -29,7 +29,7 @@ use std::time::SystemTime;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json; use serde_json;
use libpt_core::divider; use libpt_core::printing::divider;
// TYPES ///////////////////////////////////////////////////////////////////////////////////////// // TYPES /////////////////////////////////////////////////////////////////////////////////////////
@ -245,7 +245,7 @@ fn display_uptime_status(
match_format_duration_since(last_uptime) match_format_duration_since(last_uptime)
); );
debug!("\n{}", status); debug!("\n{}", status);
info!("{}", divider!()); info!("{}", divider());
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -12,7 +12,8 @@ crate-type = ["cdylib", "rlib"]
[dependencies] [dependencies]
libpt = { version = "0.3.11", path = "../.." } libpt = { version = "0.3.11", path = "../.." }
pyo3 = "0.19.0" pyo3 = { version = "0.19.0", features = ["full"] }
anyhow.workspace = true
[features] [features]
default = ["log", "core", "full"] default = ["log", "core", "full"]

View File

@ -1,11 +1,11 @@
use pyo3::prelude::*; use pyo3::prelude::*;
mod printing;
/// implement a python module in Rust /// implement a python module in Rust
#[pymodule] pub fn submodule(py: Python, parent: &PyModule) -> PyResult<()> {
#[pyo3(name = "core")] let module = PyModule::new(py, "core")?;
pub fn submodule(py: Python, m: &PyModule) -> PyResult<()> { printing::submodule(py, module)?;
let submodule = PyModule::new(py, "submodule")?; parent.add_submodule(module)?;
submodule.add("super_useful_constant", "important")?;
m.add_submodule(m)?;
Ok(()) Ok(())
} }

View File

@ -0,0 +1,24 @@
use pyo3::prelude::*;
use libpt::core::printing as origin;
/// Quickly get a one line visual divider
#[pyfunction]
pub fn divider() -> String {
origin::divider()
}
/// Quickly print a one line visual divider
#[pyfunction]
pub fn print_divider() {
origin::print_divider()
}
/// implement a python module in Rust
pub fn submodule(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "printing")?;
module.add_function(wrap_pyfunction!(divider, module)?)?;
module.add_function(wrap_pyfunction!(print_divider, module)?)?;
parent.add_submodule(module)?;
Ok(())
}

View File

@ -1,8 +1,9 @@
//! Python bindings for [`libpt`](libpt) //! Python bindings for [`libpt`](libpt)
use libpt;
#[cfg(feature = "core")] #[cfg(feature = "core")]
mod core; mod core;
#[cfg(feature = "log")]
mod log;
use pyo3::prelude::*; use pyo3::prelude::*;
@ -19,5 +20,6 @@ fn libpt_py(py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(version, m)?)?; m.add_function(wrap_pyfunction!(version, m)?)?;
#[cfg(feature = "core")] #[cfg(feature = "core")]
core::submodule(py, m)?; core::submodule(py, m)?;
log::submodule(py, m)?;
Ok(()) Ok(())
} }

View File

@ -0,0 +1,81 @@
use std::path::PathBuf;
use pyo3::prelude::*;
use libpt::log as origin;
#[derive(Clone)]
#[pyclass]
pub enum Level {
Error,
Warn,
Info,
Debug,
Trace,
}
impl From<Level> for origin::Level {
fn from(value: Level) -> Self {
match value {
Level::Error => origin::Level::ERROR,
Level::Warn => origin::Level::WARN,
Level::Info => origin::Level::INFO,
Level::Debug => origin::Level::DEBUG,
Level::Trace => origin::Level::TRACE,
}
}
}
#[pyclass]
pub struct Logger {
inner: origin::Logger,
}
impl From<origin::Logger> for Logger {
fn from(inner: origin::Logger) -> Self {
Self { inner }
}
}
#[pymethods]
impl Logger {
#[new]
pub fn build(
log_dir: Option<PathBuf>,
max_level: Option<Level>,
uptime: Option<bool>,
) -> anyhow::Result<Self> {
// concert our wrapper type
let max_level = max_level.map(origin::Level::from);
Ok(origin::Logger::build(log_dir, max_level, uptime.unwrap_or(false))?.into())
}
/// ## logging at [`Level::ERROR`]
pub fn error(&self, printable: String) {
self.inner.error(printable)
}
/// ## logging at [`Level::WARN`]
pub fn warn(&self, printable: String) {
self.inner.warn(printable)
}
/// ## logging at [`Level::INFO`]
pub fn info(&self, printable: String) {
self.inner.info(printable)
}
/// ## logging at [`Level::DEBUG`]
pub fn debug(&self, printable: String) {
self.inner.debug(printable)
}
/// ## logging at [`Level::StringRACE`]
pub fn trace(&self, printable: String) {
self.inner.trace(printable)
}
}
/// implement a python module in Rust
pub fn submodule(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "log")?;
module.add_class::<Logger>()?;
parent.add_submodule(module)?;
Ok(())
}