1use fehler::throws;
2use proc_macro2::TokenStream;
3use quote::{quote, ToTokens};
4use syn::parse::{Error, Parse, ParseStream, Result};
5use syn::{braced, bracketed, parenthesized, token};
6
7use notation_proto::prelude::ProtoEntry;
8
9use crate::core::chord::ChordDsl;
10use crate::core::tone::ToneDsl;
11use crate::core::word::WordDsl;
12use crate::fretted::pick::PickDsl;
13use crate::proto::bar::BarDsl;
14use crate::proto::entry::{EntryDsl, MultibleDsl};
15use crate::proto::layer::LayerDsl;
16use crate::proto::section::SectionDsl;
17use crate::proto::slice::SliceDsl;
18use crate::proto::track::TrackDsl;
19
20macro_rules! impl_dsl {
21 ($dsl_type:ident) => {
22 impl Parse for $dsl_type {
23 fn parse(input: ParseStream) -> Result<Self> {
24 if input.peek(token::Brace) {
25 let content;
26 braced!(content in input);
27 Self::parse_without_brace(&content)
28 } else {
29 Self::parse_without_brace(input)
30 }
31 }
32 }
33 #[allow(dead_code)]
34 impl $dsl_type {
35 #[throws(Error)]
36 pub fn parse_vec(input: ParseStream) -> Vec<$dsl_type> {
37 let mut result = vec![];
38 if input.peek(token::Bracket) {
39 let content;
40 bracketed!(content in *input);
41 while !content.is_empty() {
42 result.push(content.parse()?);
43 }
44 }
45 result
46 }
47 pub fn quote_vec(v: &[$dsl_type]) -> TokenStream {
48 let item_quotes: Vec<TokenStream> = v.iter().map(
49 |x| quote! { #x }
50 ).collect();
51 quote! {
52 vec![
53 #(#item_quotes),*
54 ]
55 }
56 }
57 }
58 }
59}
60
61impl_dsl!(EntryDsl);
62impl_dsl!(SliceDsl);
63impl_dsl!(TrackDsl);
64impl_dsl!(LayerDsl);
65impl_dsl!(BarDsl);
66impl_dsl!(SectionDsl);
67
68macro_rules! impl_multible_dsl {
69 ($dsl_type:ident) => {
70 impl Parse for $dsl_type {
71 fn parse(input: ParseStream) -> Result<Self> {
72 Self::parse_multible(input, false)
73 }
74 }
75 #[allow(dead_code)]
76 impl $dsl_type {
77 fn parse_multible(input: ParseStream, multied: bool) -> Result<Self> {
78 if input.peek(token::Paren) {
79 let content;
80 parenthesized!(content in input);
81 Self::parse_without_paren(&content, multied, true)
82 } else {
83 Self::parse_without_paren(input, multied, false)
84 }
85 }
86 #[throws(Error)]
87 pub fn parse_vec(input: ParseStream) -> Vec<$dsl_type> {
88 let mut result = vec![];
89 if input.peek(token::Bracket) {
90 let content;
91 bracketed!(content in *input);
92 while !content.is_empty() {
93 result.push(Self::parse_multible(&content, true)?);
94 }
95 }
96 result
97 }
98 pub fn quote_multible(v: &MultibleDsl<$dsl_type>) -> TokenStream {
99 let item_quotes: Vec<TokenStream> = v.items.iter().map(
100 |x| quote! { #x }
101 ).collect();
102 quote! {
103 vec![
104 #(#item_quotes),*
105 ]
106 }
107 }
108 }
109 impl Parse for MultibleDsl<$dsl_type> {
110 fn parse(input: ParseStream) -> Result<Self> {
111 let items =
112 if input.peek(token::Bracket) {
113 $dsl_type::parse_vec(input)?
114 } else {
115 vec![
116 $dsl_type::parse(input)?
117 ]
118 };
119 Ok(Self { items } )
120 }
121 }
122 impl ToTokens for MultibleDsl<$dsl_type> {
123 fn to_tokens(&self, tokens: &mut TokenStream) {
124 let item_quotes: Vec<TokenStream> = self.items.iter().map(
125 |x| quote! { #x }
126 ).collect();
127 tokens.extend(quote! {
128 #(#item_quotes),*
129 });
130 }
131 }
132 impl MultibleDsl<$dsl_type> {
133 pub fn add_proto(&self, entries: &mut Vec<ProtoEntry>) {
134 for item in self.items.iter() {
135 entries.push(item.to_proto());
136 }
137 }
138 }
139 }
140}
141
142impl_multible_dsl!(ToneDsl);
143impl_multible_dsl!(ChordDsl);
144impl_multible_dsl!(WordDsl);
145impl_multible_dsl!(PickDsl);