use std::fmt::Write;
use std::time::SystemTime;
use crate::Diagnostic;
use crate::Error;
use crate::Layout;
use crate::kv::Key;
use crate::kv::Value;
use crate::kv::Visitor;
use crate::record::Record;
#[derive(Debug, Clone, Default)]
#[non_exhaustive]
pub struct PlainTextLayout {}
struct KvWriter {
text: String,
}
impl Visitor for KvWriter {
fn visit(&mut self, key: Key, value: Value) -> Result<(), Error> {
write!(&mut self.text, " {key}={value}").unwrap();
Ok(())
}
}
impl Layout for PlainTextLayout {
fn format(&self, record: &Record, diags: &[Box<dyn Diagnostic>]) -> Result<Vec<u8>, Error> {
let mut text = String::new();
let time = record.time();
match time.duration_since(SystemTime::UNIX_EPOCH) {
Ok(dur) => {
let time = dur.as_nanos();
write!(&mut text, "{time}").unwrap();
}
Err(err) => {
let time = err.duration().as_nanos();
write!(&mut text, "-{time}").unwrap();
}
}
let level = record.level().name();
let target = record.target();
let file = record.filename();
let line = record.line().unwrap_or_default();
let message = record.payload();
write!(&mut text, " {level:>6} {target}: {file}:{line} {message}").unwrap();
let mut visitor = KvWriter { text };
record.key_values().visit(&mut visitor)?;
for d in diags {
d.visit(&mut visitor)?;
}
Ok(visitor.text.into_bytes())
}
}