azure_functions_shared_codegen/
lib.rs1#![deny(unused_extern_crates)]
5#![recursion_limit = "128"]
6#![cfg_attr(feature = "unstable", feature(proc_macro_diagnostic))]
7extern crate proc_macro;
8
9mod binding;
10
11use binding::binding_impl;
12use proc_macro2::{Delimiter, Span};
13use syn::{
14 buffer::TokenBuffer, spanned::Spanned, Attribute, AttributeArgs, Ident, Lit, Meta, NestedMeta,
15 Path, PathSegment,
16};
17
18fn last_segment_in_path(path: &Path) -> &PathSegment {
19 path.segments
20 .iter()
21 .last()
22 .expect("expected at least one segment in path")
23}
24
25fn parse_attribute_args(attr: &Attribute) -> AttributeArgs {
26 let span = attr.span();
27 let stream: proc_macro::TokenStream = match TokenBuffer::new2(attr.tokens.clone())
28 .begin()
29 .group(Delimiter::Parenthesis)
30 {
31 Some((tree, _, _)) => tree.token_stream().into(),
32 None => macro_panic(span, "failed to parse attribute"),
33 };
34
35 syn::parse_macro_input::parse::<AttributeArgs>(stream)
36 .map_err(move |e| macro_panic(span, format!("failed to parse attribute arguments: {}", e)))
37 .unwrap()
38}
39
40fn iter_attribute_args<F>(args: &[NestedMeta], mut callback: F)
41where
42 F: FnMut(&Ident, &Lit) -> bool,
43{
44 for arg in args {
45 match arg {
46 NestedMeta::Meta(m) => {
47 match m {
48 Meta::NameValue(nvp) => {
49 if !callback(&last_segment_in_path(&nvp.path).ident, &nvp.lit) {
50 return;
51 }
52 }
53 _ => macro_panic(m.span(), "expected name-value pair for an argument"),
54 };
55 }
56 _ => macro_panic(arg.span(), "expected a name-vaule pair for an argument"),
57 };
58 }
59}
60
61#[cfg(feature = "unstable")]
62fn macro_panic<T>(span: Span, message: T) -> !
63where
64 T: AsRef<str>,
65{
66 span.unstable().error(message.as_ref()).emit();
67 panic!("aborting due to previous error");
68}
69
70#[cfg(not(feature = "unstable"))]
71fn macro_panic<T>(_: Span, message: T) -> !
72where
73 T: AsRef<str>,
74{
75 panic!("{}", message.as_ref());
76}
77
78#[proc_macro_attribute]
79pub fn binding(
80 args: proc_macro::TokenStream,
81 input: proc_macro::TokenStream,
82) -> proc_macro::TokenStream {
83 binding_impl(args, input)
84}