use crate::color::{Console, Tone};
use crate::verdict::Verdict;
use std::io::Write;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ErrorBlock {
pub heading: String,
pub explanation: Option<String>,
pub remedy: Option<String>,
pub commands: Vec<String>,
}
impl ErrorBlock {
pub fn new(heading: impl Into<String>) -> Self {
Self {
heading: heading.into(),
explanation: None,
remedy: None,
commands: Vec::new(),
}
}
pub fn with_explanation(mut self, text: impl Into<String>) -> Self {
self.explanation = Some(text.into());
self
}
pub fn with_remedy(mut self, text: impl Into<String>) -> Self {
self.remedy = Some(text.into());
self
}
pub fn add_command(mut self, command: impl Into<String>) -> Self {
self.commands.push(command.into());
self
}
pub fn write_to(
&self,
console: Console,
writer: &mut (impl Write + ?Sized),
) -> std::io::Result<()> {
Verdict::Failed.write_to(console, &self.heading, writer)?;
writeln!(writer)?;
if let Some(ref exp) = self.explanation {
write!(writer, " ")?;
console.write_paint(Tone::Muted, exp, writer)?;
writeln!(writer)?;
}
if let Some(ref remedy) = self.remedy {
writeln!(writer)?;
write!(writer, " ")?;
console.write_paint(Tone::Warning, "Remedy:", writer)?;
writeln!(writer, " {remedy}")?;
}
if !self.commands.is_empty() {
writeln!(writer)?;
for cmd in &self.commands {
write!(writer, " ")?;
console.write_paint(Tone::Info, format!("$ {cmd}"), writer)?;
writeln!(writer)?;
}
}
Ok(())
}
pub fn render(&self, console: Console) -> String {
let mut buf = Vec::new();
let _ = self.write_to(console, &mut buf);
String::from_utf8(buf).unwrap_or_default()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::color::ColorMode;
#[test]
fn error_block_rendering() {
let block = ErrorBlock::new("Required toolchain is unavailable")
.with_explanation("The configured version is not installed.")
.with_remedy("Install the required toolchain:")
.add_command("toolchain install stable");
let console = Console::new(ColorMode::Never, false);
let output = block.render(console);
assert!(output.contains("[FAIL] Required toolchain is unavailable"));
assert!(output.contains("The configured version is not installed."));
assert!(output.contains("Remedy: Install the required toolchain:"));
assert!(output.contains("$ toolchain install stable"));
}
}