nix_compat_derive/internal/
ctx.rs

1use std::cell::RefCell;
2use std::fmt;
3use std::thread::panicking;
4
5use quote::ToTokens;
6
7pub struct Context {
8    errors: RefCell<Option<Vec<syn::Error>>>,
9}
10
11impl Context {
12    pub fn new() -> Context {
13        Context {
14            errors: RefCell::new(Some(Vec::new())),
15        }
16    }
17
18    pub fn syn_error(&self, error: syn::Error) {
19        self.errors.borrow_mut().as_mut().unwrap().push(error);
20    }
21
22    pub fn error_spanned<T: ToTokens, D: fmt::Display>(&self, tokens: T, message: D) {
23        self.syn_error(syn::Error::new_spanned(tokens, message));
24    }
25
26    pub fn check(&self) -> syn::Result<()> {
27        let mut iter = self.errors.borrow_mut().take().unwrap().into_iter();
28        let mut err = match iter.next() {
29            None => return Ok(()),
30            Some(err) => err,
31        };
32        for next_err in iter {
33            err.combine(next_err);
34        }
35        Err(err)
36    }
37}
38
39impl Drop for Context {
40    fn drop(&mut self) {
41        if self.errors.borrow().is_some() && !panicking() {
42            panic!("Context dropped without checking errors");
43        }
44    }
45}