use core::{cmp, fmt};
pub fn render_arguments<'a>(buf: &'a mut [u8], args: fmt::Arguments) -> &'a [u8] {
let mut writer = WriteTo::new(buf);
core::fmt::write(&mut writer, args).ok();
writer.endl();
let used = writer.used;
&buf[..used]
}
pub fn render_record<'a>(buf: &'a mut [u8], record: &log::Record) -> &'a [u8] {
render_arguments(buf, *record.args())
}
struct WriteTo<'a> {
buffer: &'a mut [u8],
used: usize,
}
impl<'a> WriteTo<'a> {
pub fn new(buffer: &'a mut [u8]) -> Self {
WriteTo { buffer, used: 0 }
}
pub fn endl(&mut self) {
if self.used < self.buffer.len() {
self.buffer[self.used] = b'\n';
self.used += 1;
}
}
}
impl<'a> core::fmt::Write for WriteTo<'a> {
fn write_str(&mut self, s: &str) -> fmt::Result {
if self.used > self.buffer.len() {
return Err(fmt::Error);
}
let remaining_buf = &mut self.buffer[self.used..];
let raw_s = s.as_bytes();
let write_num = cmp::min(raw_s.len(), remaining_buf.len());
remaining_buf[..write_num].copy_from_slice(&raw_s[..write_num]);
self.used += write_num;
if write_num < raw_s.len() {
Err(fmt::Error)
} else {
Ok(())
}
}
}
use crate::Renderer;
#[derive(Clone, Copy)]
pub struct DefaultRenderer {}
pub fn default() -> &'static DefaultRenderer {
static RENDERER: DefaultRenderer = DefaultRenderer {};
&RENDERER
}
impl Renderer for DefaultRenderer {
fn render<'a>(&self, buf: &'a mut [u8], record: &log::Record) -> &'a [u8] {
render_arguments(buf, *record.args())
}
}
unsafe impl Send for DefaultRenderer {}
unsafe impl Sync for DefaultRenderer {}
#[derive(Clone, Copy)]
pub struct RipgrepRenderer {}
impl Renderer for RipgrepRenderer {
fn render<'a>(&self, buf: &'a mut [u8], record: &log::Record) -> &'a [u8] {
match (record.file(), record.line()) {
(Some(file), Some(line)) => render_arguments(
buf,
format_args!(
"{}|{}|{}:{}: {}",
record.level(),
record.target(),
file,
line,
record.args()
),
),
(Some(file), None) => render_arguments(
buf,
format_args!(
"{}|{}|{}: {}",
record.level(),
record.target(),
file,
record.args()
),
),
_ => render_arguments(
buf,
format_args!("{}|{}: {}", record.level(), record.target(), record.args()),
),
}
}
}