notation_dsl/core/
tempo.rs

1use 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}