diff options
| author | Pg Biel <9021226+PgBiel@users.noreply.github.com> | 2023-05-03 09:20:53 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-05-03 14:20:53 +0200 |
| commit | f88ef45ee6e285df59c7aa5cec935de331b4b6e0 (patch) | |
| tree | eab5481d4b50d1d57adb4d122d7fa023dee2dcec /macros/src/util.rs | |
| parent | db6a710638cf26ddcd09b8fba74b9d1caf6cb4b8 (diff) | |
Function scopes (#1032)
Diffstat (limited to 'macros/src/util.rs')
| -rw-r--r-- | macros/src/util.rs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/macros/src/util.rs b/macros/src/util.rs index 53a8354e..6b683e5d 100644 --- a/macros/src/util.rs +++ b/macros/src/util.rs @@ -18,6 +18,27 @@ macro_rules! bail { }; } +/// For parsing attributes of the form: +/// #[attr( +/// statement; +/// statement; +/// returned_expression +/// )] +pub struct BlockWithReturn { + pub prefix: Vec<syn::Stmt>, + pub expr: syn::Stmt, +} + +impl Parse for BlockWithReturn { + fn parse(input: ParseStream) -> Result<Self> { + let mut stmts = syn::Block::parse_within(input)?; + let Some(expr) = stmts.pop() else { + return Err(input.error("expected at least one expression")); + }; + Ok(Self { prefix: stmts, expr }) + } +} + /// Whether an attribute list has a specified attribute. pub fn has_attr(attrs: &mut Vec<syn::Attribute>, target: &str) -> bool { take_attr(attrs, target).is_some() @@ -88,3 +109,16 @@ pub fn meta_line<'a>(lines: &mut Vec<&'a str>, key: &str) -> Result<&'a str> { None => bail!(callsite, "missing metadata key: {}", key), } } + +/// Creates a block responsible for building a Scope. +pub fn create_scope_builder(scope_block: Option<&BlockWithReturn>) -> TokenStream { + if let Some(BlockWithReturn { prefix, expr }) = scope_block { + quote! { { + let mut scope = ::typst::eval::Scope::deduplicating(); + #(#prefix);* + #expr + } } + } else { + quote! { ::typst::eval::Scope::new() } + } +} |
