utoipa_gen/
security_requirement.rs

1use proc_macro2::TokenStream;
2use quote::{quote, ToTokens};
3use syn::{
4    bracketed,
5    parse::{Parse, ParseStream},
6    punctuated::Punctuated,
7    token::Comma,
8    LitStr, Token,
9};
10
11use crate::Array;
12
13#[derive(Default)]
14#[cfg_attr(feature = "debug", derive(Debug))]
15pub struct SecurityRequirementsAttrItem {
16    pub name: Option<String>,
17    pub scopes: Option<Vec<String>>,
18}
19
20#[derive(Default)]
21#[cfg_attr(feature = "debug", derive(Debug))]
22pub struct SecurityRequirementsAttr(Punctuated<SecurityRequirementsAttrItem, Comma>);
23
24impl Parse for SecurityRequirementsAttr {
25    fn parse(input: ParseStream) -> syn::Result<Self> {
26        Punctuated::<SecurityRequirementsAttrItem, Comma>::parse_terminated(input)
27            .map(|o| Self(o.into_iter().collect()))
28    }
29}
30
31impl Parse for SecurityRequirementsAttrItem {
32    fn parse(input: ParseStream) -> syn::Result<Self> {
33        let name = input.parse::<LitStr>()?.value();
34
35        input.parse::<Token![=]>()?;
36
37        let scopes_stream;
38        bracketed!(scopes_stream in input);
39
40        let scopes = Punctuated::<LitStr, Comma>::parse_terminated(&scopes_stream)?
41            .iter()
42            .map(LitStr::value)
43            .collect::<Vec<_>>();
44
45        Ok(Self {
46            name: Some(name),
47            scopes: Some(scopes),
48        })
49    }
50}
51
52impl ToTokens for SecurityRequirementsAttr {
53    fn to_tokens(&self, tokens: &mut TokenStream) {
54        tokens.extend(quote! {
55            utoipa::openapi::security::SecurityRequirement::default()
56        });
57
58        for requirement in &self.0 {
59            if let (Some(name), Some(scopes)) = (&requirement.name, &requirement.scopes) {
60                let scopes = scopes.iter().collect::<Array<&String>>();
61                let scopes_len = scopes.len();
62
63                tokens.extend(quote! {
64                    .add::<&str, [&str; #scopes_len], &str>(#name, #scopes)
65                });
66            }
67        }
68    }
69}