Skip to content

Commit

Permalink
Support custom formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
YushiOMOTE committed Jul 13, 2024
1 parent ed223bc commit b7a07d5
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ mod logger;
/// The module for the serial port driver.
mod serial;

pub use crate::logger::{builder, init, init_with_filter, Builder};
pub use crate::logger::{builder, init, init_with_filter, Builder, Formatter};
pub use crate::serial::Serial;
79 changes: 58 additions & 21 deletions src/logger.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,70 @@
use crate::serial::Serial;
use core::{fmt::write, format_args};
use core::{fmt::Write, writeln};
use log::*;
use spin::Mutex;

const COM1_PORT: u16 = 0x3f8;

static LOGGER: Logger = Logger(Mutex::new(COM1_PORT));
static LOGGER: Logger = Logger::new(COM1_PORT);

struct Logger(Mutex<u16>);
/// Formatter that converts log records into desirable text format.
pub type Formatter = fn(&mut dyn Write, &Record) -> Result<(), core::fmt::Error>;

struct Inner {
base: u16,
formatter: Formatter,
}

struct Logger {
inner: Mutex<Inner>,
}

impl Logger {
const fn new(base: u16) -> Self {
Logger {
inner: Mutex::new(Inner {
base,
formatter: default_formatter,
}),
}
}

fn set_base(&self, new_base: u16) {
let mut inner = self.inner.lock();
inner.base = new_base;
}

fn set_formatter(&self, new_formatter: Formatter) {
let mut inner = self.inner.lock();
inner.formatter = new_formatter;
}
}

impl log::Log for Logger {
fn enabled(&self, _m: &Metadata) -> bool {
true
}

fn log(&self, record: &Record) {
let port = self.0.lock();
let mut serial = Serial::new(*port);

let _ = write(
&mut serial,
format_args!(
"{:>8}: {} ({}, {}:{})\n",
record.level(),
record.args(),
record.target(),
record.file().unwrap_or("<unknown>"),
record.line().unwrap_or(0),
),
);
let inner = self.inner.lock();
let mut serial = Serial::new(inner.base);

let _ = (inner.formatter)(&mut serial, record);
}

fn flush(&self) {}
}

fn set_logger_base(base: u16) {
let mut data = LOGGER.0.lock();
*data = base;
fn default_formatter(buffer: &mut dyn Write, record: &Record) -> Result<(), core::fmt::Error> {
writeln!(
buffer,
"{:>8}: {} ({}, {}:{})\n",
record.level(),
record.args(),
record.target(),
record.file().unwrap_or("<unknown>"),
record.line().unwrap_or(0)
)
}

/// The builder for a serial port logger.
Expand All @@ -45,6 +73,7 @@ fn set_logger_base(base: u16) {
pub struct Builder {
base: u16,
filter: LevelFilter,
formatter: Formatter,
}

impl Builder {
Expand All @@ -53,6 +82,7 @@ impl Builder {
Self {
base: COM1_PORT,
filter: LevelFilter::Info,
formatter: default_formatter,
}
}

Expand All @@ -68,13 +98,20 @@ impl Builder {
self
}

/// Set formatter.
pub fn formatter(mut self, formatter: Formatter) -> Self {
self.formatter = formatter;
self
}

/// Setup a logger based on the configuration.
pub fn setup(self) {
// Initialize serial port
Serial::new(self.base).init();

// Update base address of logger
set_logger_base(self.base);
LOGGER.set_base(self.base);
LOGGER.set_formatter(self.formatter);

set_logger(&LOGGER).unwrap();
set_max_level(self.filter);
Expand Down

0 comments on commit b7a07d5

Please sign in to comment.