serde_derive/internals/
ctxt.rs1use quote::ToTokens;
2use std::cell::RefCell;
3use std::fmt::Display;
4use std::thread;
5
6#[derive(Default)]
12pub struct Ctxt {
13 errors: RefCell<Option<Vec<syn::Error>>>,
16}
17
18impl Ctxt {
19 pub fn new() -> Self {
23 Ctxt {
24 errors: RefCell::new(Some(Vec::new())),
25 }
26 }
27
28 pub fn error_spanned_by<A: ToTokens, T: Display>(&self, obj: A, msg: T) {
32 self.errors
33 .borrow_mut()
34 .as_mut()
35 .unwrap()
36 .push(syn::Error::new_spanned(obj.into_token_stream(), msg));
38 }
39
40 pub fn syn_error(&self, err: syn::Error) {
42 self.errors.borrow_mut().as_mut().unwrap().push(err);
43 }
44
45 pub fn check(self) -> syn::Result<()> {
47 let mut errors = self.errors.borrow_mut().take().unwrap().into_iter();
48
49 let mut combined = match errors.next() {
50 Some(first) => first,
51 None => return Ok(()),
52 };
53
54 for rest in errors {
55 combined.combine(rest);
56 }
57
58 Err(combined)
59 }
60}
61
62impl Drop for Ctxt {
63 fn drop(&mut self) {
64 if !thread::panicking() && self.errors.borrow().is_some() {
65 panic!("forgot to check for errors");
66 }
67 }
68}