rune_alloc_macros/
context.rs

1use std::cell::RefCell;
2
3use proc_macro2::Span;
4use syn::spanned::Spanned as _;
5
6#[derive(Default)]
7pub(crate) struct Context {
8    pub(crate) errors: RefCell<Vec<syn::Error>>,
9    pub(crate) module: Option<syn::Path>,
10}
11
12impl Context {
13    /// Construct a new context.
14    pub(crate) fn new() -> Self {
15        Self::default()
16    }
17
18    /// Register an error.
19    pub(crate) fn error(&self, error: syn::Error) {
20        self.errors.borrow_mut().push(error)
21    }
22
23    /// Test if context has any errors.
24    pub(crate) fn has_errors(&self) -> bool {
25        !self.errors.borrow().is_empty()
26    }
27
28    /// Convert into errors.
29    pub(crate) fn into_errors(self) -> Vec<syn::Error> {
30        self.errors.into_inner()
31    }
32
33    pub(crate) fn tokens_with_module(&self, module: Option<&syn::Path>) -> Tokens {
34        let default_module;
35
36        let m = match module {
37            Some(module) => module,
38            None => match &self.module {
39                Some(module) => module,
40                None => {
41                    default_module = syn::Path::from(syn::Ident::new("rune", Span::call_site()));
42                    &default_module
43                }
44            },
45        };
46
47        Tokens {
48            try_clone: path(m, ["alloc", "clone", "TryClone"]),
49            alloc: path(m, ["alloc"]),
50        }
51    }
52}
53
54fn path<const N: usize>(base: &syn::Path, path: [&'static str; N]) -> syn::Path {
55    let mut base = base.clone();
56
57    for s in path {
58        let ident = syn::Ident::new(s, base.span());
59        base.segments.push(syn::PathSegment::from(ident));
60    }
61
62    base
63}
64
65pub(crate) struct Tokens {
66    pub(crate) try_clone: syn::Path,
67    pub(crate) alloc: syn::Path,
68}