use std::fmt;
#[derive(Debug, Clone)]
pub struct DebugSection {
pub title: String,
pub content: String,
pub priority: u32,
}
impl DebugSection {
pub fn new(title: impl Into<String>, content: impl Into<String>, priority: u32) -> Self {
Self {
title: title.into(),
content: content.into(),
priority,
}
}
pub fn with_header(
title: impl Into<String>,
content: impl Into<String>,
priority: u32,
) -> Self {
let title_str = title.into();
let header = format!("\n========== {title_str} ==========\n");
Self {
title: title_str,
content: format!("{}{}", header, content.into()),
priority,
}
}
}
impl fmt::Display for DebugSection {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.content)
}
}
pub trait DebugTrace: Send + Sync {
fn name(&self) -> &str;
fn debug_sections(&self) -> Vec<DebugSection>;
fn debug_summary(&self) -> Option<String> {
None
}
fn is_active(&self) -> bool {
true
}
}
pub mod Priority {
pub const PARSER: u32 = 100;
pub const BUFFER: u32 = 200;
pub const RESULTS: u32 = 300;
pub const DATATABLE: u32 = 400;
pub const DATAVIEW: u32 = 500;
pub const VIEWPORT: u32 = 600;
pub const MEMORY: u32 = 700;
pub const NAVIGATION: u32 = 800;
pub const RENDER: u32 = 900;
pub const TRACE: u32 = 1000;
pub const STATE_LOGS: u32 = 1100;
}
pub struct DebugSectionBuilder {
sections: Vec<DebugSection>,
}
impl DebugSectionBuilder {
#[must_use]
pub fn new() -> Self {
Self {
sections: Vec::new(),
}
}
pub fn add_section(
&mut self,
title: impl Into<String>,
content: impl Into<String>,
priority: u32,
) -> &mut Self {
self.sections
.push(DebugSection::with_header(title, content, priority));
self
}
pub fn add_raw(&mut self, section: DebugSection) -> &mut Self {
self.sections.push(section);
self
}
pub fn add_field(&mut self, name: &str, value: impl fmt::Display) -> &mut Self {
if let Some(last) = self.sections.last_mut() {
last.content.push_str(&format!("{name}: {value}\n"));
}
self
}
pub fn add_line(&mut self, line: impl Into<String>) -> &mut Self {
if let Some(last) = self.sections.last_mut() {
last.content.push_str(&format!("{}\n", line.into()));
}
self
}
#[must_use]
pub fn build(self) -> Vec<DebugSection> {
self.sections
}
}
impl Default for DebugSectionBuilder {
fn default() -> Self {
Self::new()
}
}