snix/tvix/nix-compat-derive/src/internal/ctx.rs
Brian Olsen ced05a2bb6 feat(tvix/nix-compat-derive): Add deriver for NixDeserialize
This adds a nix-compat-derive derive crate that implements a deriver
for NixDeserialize implementations. This is to reduce the amount of
code needed to implement deserialization for all the types used by
the Nix daemon protocol.

Change-Id: I484724b550e8a1d5e9adad9555d9dc1374ae95c2
Reviewed-on: https://cl.tvl.fyi/c/depot/+/12022
Autosubmit: Brian Olsen <me@griff.name>
Tested-by: BuildkiteCI
Reviewed-by: flokli <flokli@flokli.de>
2024-08-25 15:05:50 +00:00

50 lines
1.1 KiB
Rust

use std::cell::RefCell;
use std::fmt;
use std::thread::panicking;
use quote::ToTokens;
pub struct Context {
errors: RefCell<Option<Vec<syn::Error>>>,
}
impl Context {
pub fn new() -> Context {
Context {
errors: RefCell::new(Some(Vec::new())),
}
}
pub fn syn_error(&self, error: syn::Error) {
self.errors
.borrow_mut()
.as_mut()
.take()
.unwrap()
.push(error);
}
pub fn error_spanned<T: ToTokens, D: fmt::Display>(&self, tokens: T, message: D) {
self.syn_error(syn::Error::new_spanned(tokens, message));
}
pub fn check(&self) -> syn::Result<()> {
let mut iter = self.errors.borrow_mut().take().unwrap().into_iter();
let mut err = match iter.next() {
None => return Ok(()),
Some(err) => err,
};
for next_err in iter {
err.combine(next_err);
}
Err(err)
}
}
impl Drop for Context {
fn drop(&mut self) {
if self.errors.borrow().is_some() && !panicking() {
panic!("Context dropped without checking errors");
}
}
}