1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
use proc_macro2::TokenStream; use quote::ToTokens; use syn::{ parse::{Parse, ParseStream, Result}, Expr, Ident, Token, }; use crate::refident::RefIdent; #[derive(Debug, PartialEq, Clone)] pub(crate) struct ValueList { pub(crate) arg: Ident, pub(crate) values: Vec<Expr>, } impl Parse for ValueList { fn parse(input: ParseStream) -> Result<Self> { let arg = input.parse()?; let _to: Token![=>] = input.parse()?; let content; let paren = syn::bracketed!(content in input); let values = content .parse_terminated::<_, Token![,]>(Parse::parse)? .into_iter() .collect(); let ret = Self { arg, values }; if ret.values.len() == 0 { Err(syn::Error::new( paren.span, "Values list should not be empty", )) } else { Ok(ret) } } } impl RefIdent for ValueList { fn ident(&self) -> &Ident { &self.arg } } impl ToTokens for ValueList { fn to_tokens(&self, tokens: &mut TokenStream) { self.arg.to_tokens(tokens) } } #[cfg(test)] mod should { use crate::test::{assert_eq, *}; use super::*; mod parse_values_list { use super::assert_eq; use super::*; fn parse_values_list<S: AsRef<str>>(values_list: S) -> ValueList { parse_meta(values_list) } #[test] fn some_literals() { let literals = literal_expressions_str(); let name = "argument"; let values_list = parse_values_list(format!( r#"{} => [{}]"#, name, literals .iter() .map(ToString::to_string) .collect::<Vec<String>>() .join(", ") )); assert_eq!(name, &values_list.arg.to_string()); assert_eq!(values_list.args(), to_args!(literals)); } #[test] fn raw_code() { let values_list = parse_values_list(r#"no_mater => [vec![1,2,3]]"#); assert_eq!(values_list.args(), to_args!(["vec![1, 2, 3]"])); } #[test] #[should_panic] fn raw_code_with_parsing_error() { parse_values_list(r#"other => [some:<>(1,2,3)]"#); } #[test] #[should_panic(expected = r#"expected square brackets"#)] fn forget_brackets() { parse_values_list(r#"other => 42"#); } } }