Skip to content

Commit

Permalink
Split the Logger trait, LogLevel and structs implementing `Logger…
Browse files Browse the repository at this point in the history
…` trait.
  • Loading branch information
dousamichal0807 committed Apr 13, 2022
1 parent 1a16442 commit 9415d26
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 103 deletions.
24 changes: 24 additions & 0 deletions src/auto.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use crate::LogLevel;

use std::io;

/// Trait for implementing a logging utility.
///
/// This trait has only one method, that is [`log`]. This method is called whenever
/// some operation, that may be important, happens.
///
/// Note that [`Logger`] trait does not specify how given message is logged nor
/// where it should be logged to.
pub trait Logger {
/// Method for logging a message.
///
/// # Parameters
///
/// - `log_level`: [`LogLevel`] of given message
/// - `message`: message text to be logged
///
/// # Return value
///
/// [`std::io::Result`]`<()>` indicating, whether the message was successfully logged
fn log(&mut self, log_level: LogLevel, message: &str) -> io::Result<()>;
}
68 changes: 68 additions & 0 deletions src/level.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use std::cmp::Ordering;
use std::fmt;
use std::fmt::Display;
use std::fmt::Formatter;

/// Represents how important a log message is.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum LogLevel {
/// [`LogLevel`] for debugging purposes.
Debug,

/// [`LogLevel`] for informational messages.
Info,

/// [`LogLevel`] for messages that warns the user of application about potential risks.
Warning,

/// [`LogLevel`] for messages that informs the user that something went wrong and the error is
/// cannot be corrected, but the application can continue running.
Error,

/// [`LogLevel`] for messages that informs the user that something went wrong and the error is
/// unrecoverable and the application cannot continue.
Fatal,
}

impl LogLevel {
/// Describes the [`LogLevel`] as a number ([`u8`]).
///
/// # Return value
///
/// [`LogLevel`] represented as an [`u8`]
pub fn numeric_level(&self) -> u8 {
match self {
Self::Debug => 0,
Self::Info => 1,
Self::Warning => 2,
Self::Error => 3,
Self::Fatal => 4,
}
}
}

impl Display for LogLevel {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
writeln!(f, "{}",
match self {
Self::Debug => "DEBUG",
Self::Info => "INFO",
Self::Warning => "WARN",
Self::Error => "ERROR",
Self::Fatal => "FATAL",
}
)
}
}

impl PartialOrd for LogLevel {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Option::Some(self.cmp(other))
}
}

impl Ord for LogLevel {
fn cmp(&self, other: &Self) -> Ordering {
self.numeric_level().cmp(&other.numeric_level())
}
}
117 changes: 21 additions & 96 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,96 +1,21 @@
pub mod composite;
pub mod text;

pub use self::composite::CompositeLogger;
pub use self::text::TextLogger;

use std::cmp::Ordering;
use std::fmt;
use std::fmt::Display;
use std::fmt::Formatter;
use std::io;

/// Trait for implementing a logging utility.
///
/// This trait has only one method, that is [`log`]. This method is called whenever
/// some operation, that may be important, happens.
///
/// Note that [`Logger`] trait does not specify how given message is logged nor
/// where it should be logged to.
pub trait Logger {
/// Method for logging a message.
///
/// # Parameters
///
/// - `log_level`: [`LogLevel`] of given message
/// - `message`: message text to be logged
///
/// # Return value
///
/// [`std::io::Result`]`<()>` indicating, whether the message was successfully logged
fn log(&mut self, log_level: LogLevel, message: &str) -> io::Result<()>;
}

/// Represents how important a log message is.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum LogLevel {
/// [`LogLevel`] for debugging purposes.
Debug,

/// [`LogLevel`] for informational messages.
Info,

/// [`LogLevel`] for messages that warns the user of application about potential risks.
Warning,

/// [`LogLevel`] for messages that informs the user that something went wrong and the error is
/// cannot be corrected, but the application can continue running.
Error,

/// [`LogLevel`] for messages that informs the user that something went wrong and the error is
/// unrecoverable and the application cannot continue.
Fatal,
}

impl LogLevel {
/// Describes the [`LogLevel`] as a number ([`u8`]).
///
/// # Return value
///
/// [`LogLevel`] represented as an [`u8`]
pub fn numeric_level(&self) -> u8 {
match self {
Self::Debug => 0,
Self::Info => 1,
Self::Warning => 2,
Self::Error => 3,
Self::Fatal => 4,
}
}
}

impl Display for LogLevel {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
writeln!(f, "{}",
match self {
Self::Debug => "DEBUG",
Self::Info => "INFO",
Self::Warning => "WARN",
Self::Error => "ERROR",
Self::Fatal => "FATAL",
}
)
}
}

impl PartialOrd for LogLevel {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Option::Some(self.cmp(other))
}
}

impl Ord for LogLevel {
fn cmp(&self, other: &Self) -> Ordering {
self.numeric_level().cmp(&other.numeric_level())
}
}
//! A simple crate for logging.
//!
//! # The [`Logger`] trait
//!
//! All loggers implement [`Logger`] trait. See [`Logger`] trait for more
//! information.
//!
//! # Featured logger types
//!
//! - [`CompositeLogger`](crate::loggers::CompositeLogger)
//! - [`TextLogger`](crate::loggers::TextLogger)
#![forbid(unsafe_code)]
#![forbid(unused_crate_dependencies)]
#![forbid(unused_extern_crates)]

pub mod auto;
pub mod level;
pub mod loggers;

pub use crate::auto::Logger;
pub use crate::level::LogLevel;
5 changes: 5 additions & 0 deletions src/loggers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub mod composite;
pub mod text;

pub use self::composite::CompositeLogger;
pub use self::text::TextLogger;
16 changes: 9 additions & 7 deletions src/composite.rs → src/loggers/composite.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::borrow::Borrow;
use std::borrow::BorrowMut;
use std::io;
use std::ops::Deref;
use std::ops::DerefMut;

use crate::Logger;
use crate::LogLevel;
Expand All @@ -9,7 +9,7 @@ type LoggerVec = Vec<Box<dyn Logger + Send + Sync>>;

/// Represents a [`Logger`] that consists of many [`Logger`]s.
///
/// [`CompositeLogger`] is used through its [`Borrow`] and [`BorrowMut`]
/// [`CompositeLogger`] is used through its [`Deref`] and [`DerefMut`]
/// implementations which yield a borrow to the inner [`Vec`] of [`Logger`]s.
pub struct CompositeLogger (LoggerVec);

Expand All @@ -35,14 +35,16 @@ impl Logger for CompositeLogger {
}
}

impl Borrow<LoggerVec> for CompositeLogger {
fn borrow(&self) -> &LoggerVec {
impl Deref for CompositeLogger {
type Target = LoggerVec;

fn deref(&self) -> &LoggerVec {
&self.0
}
}

impl BorrowMut<LoggerVec> for CompositeLogger {
fn borrow_mut(&mut self) -> &mut LoggerVec {
impl DerefMut for CompositeLogger {
fn deref_mut(&mut self) -> &mut LoggerVec {
&mut self.0
}
}

0 comments on commit 9415d26

Please sign in to comment.