notation_dsl/core/
tempo.rs1use fehler::throws;
2
3use notation_proto::prelude::Tempo;
4use proc_macro2::TokenStream;
5use quote::{quote, ToTokens};
6use syn::parse::{Error, Parse, ParseStream};
7use syn::{Ident, LitInt};
8
9pub struct TempoDsl {
10 pub tempo: Tempo,
11}
12
13impl Parse for TempoDsl {
14 #[throws(Error)]
15 fn parse(input: ParseStream) -> Self {
16 let tempo = if input.peek(LitInt) {
17 let bpm = input.parse::<LitInt>()?.base10_parse::<u16>()?;
18 Tempo::Bpm(bpm)
19 } else {
20 let ident = input.parse::<Ident>()?;
21 Tempo::from_ident(ident.to_string().as_str())
22 };
23 TempoDsl { tempo }
24 }
25}
26
27impl TempoDsl {
28 pub fn peek(input: ParseStream) -> bool {
29 input.peek(LitInt) || input.peek(Ident)
30 }
31}
32
33impl ToTokens for TempoDsl {
34 fn to_tokens(&self, tokens: &mut TokenStream) {
35 let TempoDsl { tempo } = self;
36 let tempo_ident = tempo.to_ident();
37 tokens.extend(quote! {
38 Tempo::from_ident(#tempo_ident)
39 });
40 }
41}
42
43impl TempoDsl {
44 pub fn to_proto(&self) -> Tempo {
45 self.tempo
46 }
47}