Sha256: 83a4e6fbe0e439d578478883594407e03f2f340541be479bdf0b04a202633a37
Contents?: true
Size: 1.97 KB
Versions: 30
Compression:
Stored size: 1.97 KB
Contents
use quote::ToTokens; use std::cell::RefCell; use std::fmt::Display; use std::thread; /// A type to collect errors together and format them. /// /// Dropping this object will cause a panic. It must be consumed using `check`. /// /// References can be shared since this type uses run-time exclusive mut checking. #[derive(Default)] pub struct Ctxt { // The contents will be set to `None` during checking. This is so that checking can be // enforced. errors: RefCell<Option<Vec<syn::Error>>>, } impl Ctxt { /// Create a new context object. /// /// This object contains no errors, but will still trigger a panic if it is not `check`ed. pub fn new() -> Self { Ctxt { errors: RefCell::new(Some(Vec::new())), } } /// Add an error to the context object with a tokenenizable object. /// /// The object is used for spanning in error messages. pub fn error_spanned_by<A: ToTokens, T: Display>(&self, obj: A, msg: T) { self.errors .borrow_mut() .as_mut() .unwrap() // Curb monomorphization from generating too many identical methods. .push(syn::Error::new_spanned(obj.into_token_stream(), msg)); } /// Add one of Syn's parse errors. pub fn syn_error(&self, err: syn::Error) { self.errors.borrow_mut().as_mut().unwrap().push(err); } /// Consume this object, producing a formatted error string if there are errors. pub fn check(self) -> syn::Result<()> { let mut errors = self.errors.borrow_mut().take().unwrap().into_iter(); let mut combined = match errors.next() { Some(first) => first, None => return Ok(()), }; for rest in errors { combined.combine(rest); } Err(combined) } } impl Drop for Ctxt { fn drop(&mut self) { if !thread::panicking() && self.errors.borrow().is_some() { panic!("forgot to check for errors"); } } }
Version data entries
30 entries across 30 versions & 1 rubygems