kvapi_macros_internals/api/
headers.rs1use super::common::Separator;
2use proc_macro2::TokenStream;
3use quote::quote;
4use syn::{
5 braced, bracketed,
6 parse::{Parse, ParseStream},
7 parse_str, Expr, Ident, LitStr, Token,
8};
9
10#[derive(Clone, Debug)]
19pub struct Headers {
20 pub client: Vec<TokenStream>,
21 pub query: Vec<TokenStream>,
22}
23
24impl Parse for Headers {
25 fn parse(input: ParseStream) -> syn::Result<Self> {
26 let mut headers: Vec<Header> = vec![];
27 let mut client_headers: Vec<TokenStream> = vec![];
28 let mut query_headers: Vec<TokenStream> = vec![];
29
30 let args;
32 braced!(args in input);
33 while !args.is_empty() {
34 let header: Header = args.parse()?;
35 if !headers.contains(&header) {
36 headers.push(header);
37 }
38 args.parse::<Option<Token![,]>>()?;
39 }
40
41 let _ = headers
43 .iter()
44 .map(|header| {
45 let key = &header.key;
46 let value = parse_str::<Expr>(&header.value).expect("expected Header");
47
48 if header.is_query == true {
50 query_headers.push(quote! {
51 .header(#key, #value)
53 });
54 } else {
55 client_headers.push(quote! {
56 let value = #value;
58 headers.insert(#key, kvapi::HeaderValue::from_str(value).unwrap());
59 });
60 }
61 })
62 .collect::<Vec<_>>();
63
64 Ok(Self {
65 client: client_headers,
66 query: query_headers,
67 })
68 }
69}
70
71#[derive(Hash, Eq, PartialEq)] pub struct Header {
76 pub key: String,
77 pub value: String, pub is_query: bool,
79}
80
81impl Parse for Header {
82 fn parse(input: ParseStream) -> syn::Result<Self> {
83 let mut is_query = false;
84
85 if input.peek(Token![#]) {
87 input.parse::<Token![#]>()?;
88 let attrs;
89 bracketed!(attrs in input);
90 let _ = attrs
91 .parse_terminated(Attr::parse, Token![,])?
92 .into_iter()
93 .map(|attr| match attr.key.to_string().as_str() {
94 "query" => is_query = true,
95 "client" => {}
96 _ => panic!("unexpected header attribute"),
97 })
98 .collect::<Vec<()>>();
99 }
100
101 let key: String = input.parse::<LitStr>()?.value();
103 input.parse::<Separator>()?;
104 let value: Expr = input.parse()?;
105 let value = quote!( #value ).to_string();
106
107 Ok(Self {
108 key,
109 value,
110 is_query,
111 })
112 }
113}
114
115pub struct Attr {
122 pub key: Ident,
123}
124
125impl Parse for Attr {
126 fn parse(input: ParseStream) -> syn::Result<Self> {
127 let key = input.parse::<Ident>()?;
128 Ok(Self { key })
129 }
130}