utoipa_gen/
security_requirement.rs1use 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 SecurityRequirementAttr {
16 name: Option<String>,
17 scopes: Option<Vec<String>>,
18}
19
20impl Parse for SecurityRequirementAttr {
21 fn parse(input: ParseStream) -> syn::Result<Self> {
22 if input.is_empty() {
23 return Ok(Self {
24 ..Default::default()
25 });
26 }
27 let name = input.parse::<LitStr>()?.value();
28 input.parse::<Token![=]>()?;
29
30 let scopes_stream;
31 bracketed!(scopes_stream in input);
32 let scopes = Punctuated::<LitStr, Comma>::parse_terminated(&scopes_stream)?
33 .iter()
34 .map(LitStr::value)
35 .collect::<Vec<_>>();
36
37 Ok(Self {
38 name: Some(name),
39 scopes: Some(scopes),
40 })
41 }
42}
43
44impl ToTokens for SecurityRequirementAttr {
45 fn to_tokens(&self, tokens: &mut TokenStream) {
46 if let (Some(name), Some(scopes)) = (&self.name, &self.scopes) {
47 let scopes_array = scopes.iter().collect::<Array<&String>>();
48 let scopes_len = scopes.len();
49
50 tokens.extend(quote! {
51 utoipa::openapi::security::SecurityRequirement::new::<&str, [&str; #scopes_len], &str>(#name, #scopes_array)
52 })
53 } else {
54 tokens.extend(quote! {
55 utoipa::openapi::security::SecurityRequirement::default()
56 })
57 }
58 }
59}