1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
use std::fmt::Display; use std::cell::RefCell; #[derive(Default)] pub struct Ctxt { errors: RefCell<Option<Vec<String>>>, } impl Ctxt { pub fn new() -> Self { Ctxt { errors: RefCell::new(Some(Vec::new())) } } pub fn error<T: Display>(&self, msg: T) { self.errors.borrow_mut().as_mut().unwrap().push(msg.to_string()); } pub fn check(self) -> Result<(), String> { let mut errors = self.errors.borrow_mut().take().unwrap(); match errors.len() { 0 => Ok(()), 1 => Err(errors.pop().unwrap()), n => { let mut msg = format!("{} errors:", n); for err in errors { msg.push_str("\n\t# "); msg.push_str(&err); } Err(msg) } } } } impl Drop for Ctxt { fn drop(&mut self) { if self.errors.borrow().is_some() { panic!("forgot to check for errors"); } } }