bon_macros/collections/
map.rs
1use crate::util::prelude::*;
2use syn::parse::ParseStream;
3use syn::punctuated::Punctuated;
4use syn::{Expr, Token};
5
6pub(crate) fn parse_macro_input(
7 input: ParseStream<'_>,
8) -> Result<Punctuated<(Expr, Expr), Token![,]>, syn::Error> {
9 Punctuated::parse_terminated_with(input, parse_map_pair)
10}
11
12fn parse_map_pair(pair: ParseStream<'_>) -> Result<(Expr, Expr), syn::Error> {
13 let key = pair.parse().map_err(|_| pair.error(pair))?;
14 let _: Token![:] = pair.parse()?;
15 let value = pair.parse()?;
16
17 Ok((key, value))
18}
19
20pub(crate) fn generate(entries: Punctuated<(Expr, Expr), Token![,]>) -> TokenStream {
21 let error =
22 super::validate_expressions_are_unique("key in the map", entries.iter().map(|(k, _)| k));
23
24 let items = entries.into_iter().map(|(key, value)| {
25 quote!((
26 ::core::convert::Into::into(#key),
27 ::core::convert::Into::into(#value),
28 ))
29 });
30
31 let output = quote! {
32 ::core::iter::FromIterator::from_iter([
33 #(#items),*
34 ])
35 };
36
37 error
41 .map(|err| {
42 let err = err.write_errors();
43 quote! {{
44 #err
45 #output
46 }}
47 })
48 .unwrap_or(output)
49}