error.rs 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. use std::{io, io::Write, process};
  2. use termion::{color, style};
  3. pub(super) struct ErrorEmitter {
  4. namespace: String,
  5. file: String,
  6. lines: Vec<String>,
  7. }
  8. impl ErrorEmitter {
  9. pub fn new(namespace: &str, file: &str, lines: Vec<String>) -> Self {
  10. Self { namespace: namespace.to_string(), file: file.to_string(), lines }
  11. }
  12. pub fn emit(&self, msg: String, ln: usize, col: usize) {
  13. let err_msg = format!("{} (line {}, column {})", msg, ln, col);
  14. let dbg_msg = format!("{}:{}:{}: {}", self.file, ln, col, self.lines[ln - 1]);
  15. let pad = dbg_msg.split(": ").next().unwrap().len() + col + 2;
  16. let caret = format!("{:width$}^", "", width = pad);
  17. let msg = format!("{}\n{}\n{}\n", err_msg, dbg_msg, caret);
  18. self.abort(&msg);
  19. }
  20. fn abort(&self, msg: &str) {
  21. let stderr = io::stderr();
  22. let mut handle = stderr.lock();
  23. write!(
  24. handle,
  25. "{}{}{} error:{} {}",
  26. style::Bold,
  27. color::Fg(color::Red),
  28. self.namespace,
  29. style::Reset,
  30. msg,
  31. )
  32. .unwrap();
  33. handle.flush().unwrap();
  34. process::exit(1);
  35. }
  36. }