diff --git a/bng_macros/Cargo.toml b/bng_macros/Cargo.toml index 1f75c20..238ebf8 100644 --- a/bng_macros/Cargo.toml +++ b/bng_macros/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" proc-macro = true [dependencies] +Inflector = "0.11.4" proc-macro2 = "1.0" quote = "1.0" syn = { version = "2.0", features = ["full"] } diff --git a/bng_macros/src/lib.rs b/bng_macros/src/lib.rs index 2ea9f67..bed291d 100644 --- a/bng_macros/src/lib.rs +++ b/bng_macros/src/lib.rs @@ -1,8 +1,9 @@ extern crate proc_macro; +use inflector::Inflector; use proc_macro::TokenStream; use proc_macro2::Span; -use quote::quote; -use syn::{parse_macro_input, Data, DataEnum, DeriveInput, Ident}; +use quote::{quote, ToTokens}; +use syn::{parse_macro_input, Data, DataEnum, DeriveInput, Fields, FieldsUnnamed, Ident}; #[proc_macro_derive(SlopeModifierParser)] pub fn slope_modifier_parser(input: TokenStream) -> TokenStream { @@ -16,24 +17,49 @@ pub fn quick_modifier_parser(input: TokenStream) -> TokenStream { impl_quick_modifier_parser(ast) } +#[proc_macro_derive(ModifierParser)] +pub fn modifier_parser(input: TokenStream) -> TokenStream { + let ast = parse_macro_input!(input as DeriveInput); + impl_modifier_parser(ast) +} + +trait ToIdent: ToString { + fn to_ident(&self) -> Ident { + Ident::new(&self.to_string(), Span::call_site()) + } +} + +impl ToIdent for S {} + fn impl_slope_modifier_parser(ast: DeriveInput) -> TokenStream { let name = &ast.ident; + let fn_name = name.to_string().to_snake_case().to_ident(); if let Data::Enum(DataEnum { variants, .. }) = ast.data { let match_arms = variants.iter().map(|variant| { let variant_name = &variant.ident; - let const_name = Ident::new(&variant.ident.to_string().to_uppercase(),Span::call_site()); + let variant_name_lower = variant_name.to_string().to_lowercase().to_ident(); + let const_name = &variant.ident.to_string().to_uppercase().to_ident(); quote! { - nom::combinator::value(#name::#variant_name, nom::character::complete::char(SlopeModifier::#const_name)) + nom::error::context( + stringify!(#variant_name_lower), + nom::combinator::value( + #name::#variant_name, + nom::character::complete::char(SlopeModifier::#const_name) + ) + ) } }); quote! { - impl lex::lexer::Parse for #name { - fn parse(input: &str) -> nom::IResult<&str, #name> { + pub fn #fn_name<'a, E: nom::error::ParseError<&'a str> + nom::error::ContextError<&'a str>>( + i: &'a str, + ) -> nom::IResult<&'a str, #name, E> { + nom::error::context( + "slope modifier", nom::branch::alt(( #(#match_arms),* - ))(input) - } + )) + )(i) } } .into() @@ -44,37 +70,110 @@ fn impl_slope_modifier_parser(ast: DeriveInput) -> TokenStream { fn impl_quick_modifier_parser(ast: DeriveInput) -> TokenStream { let name = &ast.ident; + let fn_name = name.to_string().to_snake_case().to_ident(); if let Data::Enum(DataEnum { variants, .. }) = ast.data { let match_arms = variants.iter().map(|variant| { let variant_name = &variant.ident; - let const_name = - Ident::new(&variant.ident.to_string().to_uppercase(), Span::call_site()); + let variant_name_lower = variant_name.to_string().to_lowercase().to_ident(); + let const_name = &variant.ident.to_string().to_uppercase().to_ident(); quote! { - nom::combinator::map( - nom::branch::alt( - ( - nom::combinator::value( - lex::UP, - nom::character::complete::char(#name::#const_name.0) - ), - nom::combinator::value( - lex::DOWN, - nom::character::complete::char(#name::#const_name.1) + nom::error::context( + stringify!(#variant_name_lower), + nom::combinator::map( + nom::branch::alt( + ( + nom::combinator::value( + lex::UP, + nom::character::complete::char(#name::#const_name.0) + ), + nom::combinator::value( + lex::DOWN, + nom::character::complete::char(#name::#const_name.1) + ) ) - ) - ), - #name::#variant_name + ), + #name::#variant_name + ) ) } }); quote! { - impl lex::lexer::Parse for #name { - fn parse(input: &str) -> nom::IResult<&str, #name> { + pub fn #fn_name<'a, E: nom::error::ParseError<&'a str> + nom::error::ContextError<&'a str>>( + i: &'a str, + ) -> nom::IResult<&'a str, #name, E> { + nom::error::context( + "quick modifier", nom::branch::alt(( #(#match_arms),* - ))(input) - } + )) + )(i) + } + } + .into() + } else { + panic!("this macro only works on enums") + } +} + +fn impl_modifier_parser(ast: DeriveInput) -> TokenStream { + let name = &ast.ident; + let fn_name = name.to_string().to_snake_case().to_ident(); + if let Data::Enum(DataEnum { variants, .. }) = ast.data { + let match_arms = variants.iter().map(|variant| { + let variant_name = &variant.ident; + let variant_name_lower = variant_name.to_string().to_lowercase().to_ident(); + let const_name = &variant.ident.to_string().to_uppercase().to_ident(); + if let Fields::Unnamed(FieldsUnnamed { + paren_token: _, + unnamed, + }) = &variant.fields + { + let type_name = { + let type_name = &unnamed[0].ty.to_token_stream().to_string(); + match type_name.strip_prefix("NonZero") { + Some(s) => { + let lower = s.to_lowercase().to_ident(); + let type_name = &unnamed[0].ty; + quote! { + nom::combinator::map_opt( + nom::character::complete::#lower, + std::num::#type_name::new + ) + } + } + _ => { + let type_name = &unnamed[0].ty; + quote! { + nom::character::complete::#type_name + } + } + } + }; + quote! { + nom::error::context( + stringify!(#variant_name_lower), + nom::combinator::map( + nom::sequence::preceded(nom::character::complete::char(#name::#const_name), #type_name), + #name::#variant_name + ) + ) + } + } else { + panic!("this macro only works on unnamed fields") + } + }); + + quote! { + pub fn #fn_name<'a, E: nom::error::ParseError<&'a str> + nom::error::ContextError<&'a str>>( + i: &'a str, + ) -> nom::IResult<&'a str, #name, E> { + nom::error::context( + "modifier", + nom::branch::alt(( + #(#match_arms),* + )) + )(i) } } .into() diff --git a/src/bng/score.rs b/src/bng/score.rs index 84ba46c..df2b65b 100644 --- a/src/bng/score.rs +++ b/src/bng/score.rs @@ -5,10 +5,10 @@ use std::{ use amplify::From; use anyhow::Context; -use bng_macros::{QuickModifierParser, SlopeModifierParser}; +use bng_macros::{ModifierParser, QuickModifierParser, SlopeModifierParser}; use derive_new::new; use derived_deref::Deref; -use lex::lexer::flat_atom_parser; +use lex::lexer::atom; use nom::{ branch::alt, character::{complete::char, streaming::one_of}, @@ -91,7 +91,7 @@ impl Clone for FlatAtom { } } -#[derive(Clone)] +#[derive(Clone, ModifierParser)] #[cfg_attr(debug_assertions, derive(Debug, PartialEq))] pub enum Modifier { Volume(u8), diff --git a/src/bng/score/de.rs b/src/bng/score/de.rs index aa97ecd..0ee1b57 100644 --- a/src/bng/score/de.rs +++ b/src/bng/score/de.rs @@ -12,7 +12,7 @@ use serde::{ }; use thiserror::Error; -use crate::bng::score::lex::lexer::flat_atom_parser; +use crate::bng::score::lex::lexer::atom; use super::{ utils::{inflate, InflateError}, @@ -64,7 +64,7 @@ impl<'de> Deserialize<'de> for Atoms { if sheet.is_empty() { Ok(Default::default()) } else { - flat_atom_parser_mapper::(&sheet, flat_atom_parser(¬es)) + atom_mapper::(&sheet, atom(¬es)) } } } @@ -76,7 +76,7 @@ where many0(one_of(" \t\r")) } -fn flat_atom_parser_mapper<'a, 'de, D, P>( +fn atom_mapper<'a, 'de, D, P>( input: &'a str, parser: P, ) -> Result>::Error> diff --git a/src/bng/score/lex/lexer.rs b/src/bng/score/lex/lexer.rs index 762100e..68ce93c 100644 --- a/src/bng/score/lex/lexer.rs +++ b/src/bng/score/lex/lexer.rs @@ -10,41 +10,28 @@ use nom::{ bytes::complete::{take_till, take_till1}, character::complete::{anychar, char, one_of, space1, u16, u8}, combinator::{map_opt, map_res, opt, value, verify}, + error::{context, ContextError, ParseError}, multi::many0, sequence::{delimited, pair, preceded, separated_pair, terminated}, Err, IResult, Parser, }; +use crate::bng::score::{modifier, quick_modifier, slope_modifier}; + use super::{ - super::super::Expression as Instruction, - {Atom, FlatAtom, Modifier, QuickModifier, SlopeModifier}, + super::super::Expression as Instruction, Atom, FlatAtom, Modifier, QuickModifier, SlopeModifier, }; #[cfg(test)] mod tests; -pub(crate) trait Parse: Sized { - fn parse(input: &str) -> IResult<&str, Self>; -} - -impl Parse for Modifier { - fn parse(input: &str) -> IResult<&str, Self> { - alt(( - preceded(char(Modifier::VOLUME), u8).map(Modifier::Volume), - preceded(char(Modifier::OCTAVE), u8).map(Modifier::Octave), - preceded(char(Modifier::LENGTH), map_opt(u8, NonZeroU8::new)).map(Modifier::Length), - preceded(char(Modifier::TEMPO), map_opt(u16, NonZeroU16::new)).map(Modifier::Tempo), - ))(input) - } -} - -pub fn flat_atom_parser(notes: &str) -> impl Parser<&str, FlatAtom, nom::error::Error<&str>> { +pub fn atom(notes: &str) -> impl Parser<&str, FlatAtom, nom::error::Error<&str>> { alt(( map_res(map_opt(one_of(notes), |c| notes.find(c)), u8::try_from).map(FlatAtom::Note), value(FlatAtom::Rest, char(Atom::REST)), value(FlatAtom::StartHere, char(Atom::START_HERE)), - preceded(char(Atom::MODIFIER), Modifier::parse).map(FlatAtom::Modifier), - QuickModifier::parse.map(FlatAtom::QuickModifier), + preceded(char(Atom::MODIFIER), modifier).map(FlatAtom::Modifier), + quick_modifier.map(FlatAtom::QuickModifier), preceded( char(Atom::LOOP.0), map_opt(opt(u8), |n| { @@ -63,7 +50,7 @@ pub fn flat_atom_parser(notes: &str) -> impl Parser<&str, FlatAtom, nom::error:: preceded( char(Atom::SLOPE.0), separated_pair( - SlopeModifier::parse, + slope_modifier, char(' '), map_res(take_till1(|c| c == ','), |s: &str| { s.parse() diff --git a/src/bng/score/lex/lexer/tests.rs b/src/bng/score/lex/lexer/tests.rs index 96a4af7..a343048 100644 --- a/src/bng/score/lex/lexer/tests.rs +++ b/src/bng/score/lex/lexer/tests.rs @@ -15,8 +15,8 @@ mod flat_atom { use nom::Parser; use super::super::{ - super::super::super::Expression as Instruction, super::UP, flat_atom_parser, Atom, - FlatAtom, Modifier, QuickModifier, SlopeModifier, + super::super::super::Expression as Instruction, super::UP, atom, Atom, FlatAtom, Modifier, + QuickModifier, SlopeModifier, }; use super::*; @@ -35,7 +35,7 @@ mod flat_atom { fn note() { assert_eq!( Ok((SAMPLE_STR, FlatAtom::Note(2))), - flat_atom_parser("abcdefg").parse(concatcp!('c', SAMPLE_STR)) + atom("abcdefg").parse(concatcp!('c', SAMPLE_STR)) ) } @@ -43,7 +43,7 @@ mod flat_atom { fn rest() { assert_eq!( Ok((SAMPLE_STR, FlatAtom::Rest)), - flat_atom_parser("abcdefg").parse(concatcp!(Atom::REST, SAMPLE_STR)) + atom("abcdefg").parse(concatcp!(Atom::REST, SAMPLE_STR)) ) } @@ -51,7 +51,7 @@ mod flat_atom { fn start_here() { assert_eq!( Ok((SAMPLE_STR, FlatAtom::StartHere)), - flat_atom_parser("abcdefg").parse(concatcp!(Atom::START_HERE, SAMPLE_STR)) + atom("abcdefg").parse(concatcp!(Atom::START_HERE, SAMPLE_STR)) ) } @@ -62,12 +62,7 @@ mod flat_atom { SAMPLE_STR, FlatAtom::Modifier(Modifier::Length(unsafe { NonZeroU8::new_unchecked(2) })) )), - flat_atom_parser("abcdefg").parse(concatcp!( - Atom::MODIFIER, - Modifier::LENGTH, - 2u8, - SAMPLE_STR - )) + atom("abcdefg").parse(concatcp!(Atom::MODIFIER, Modifier::LENGTH, 2u8, SAMPLE_STR)) ) } @@ -78,7 +73,7 @@ mod flat_atom { SAMPLE_STR, FlatAtom::QuickModifier(QuickModifier::Length(UP)) )), - flat_atom_parser("abcdefg").parse(concatcp!(QuickModifier::LENGTH.0, SAMPLE_STR)) + atom("abcdefg").parse(concatcp!(QuickModifier::LENGTH.0, SAMPLE_STR)) ) } @@ -89,21 +84,21 @@ mod flat_atom { SAMPLE_STR, FlatAtom::LoopStarts(unsafe { NonZeroU8::new_unchecked(3) }) )), - flat_atom_parser("abcdefg").parse(concatcp!(Atom::LOOP.0, 3u8, SAMPLE_STR)) + atom("abcdefg").parse(concatcp!(Atom::LOOP.0, 3u8, SAMPLE_STR)) ); assert_eq!( Ok(( SAMPLE_STR, FlatAtom::LoopStarts(unsafe { NonZeroU8::new_unchecked(2) }) )), - flat_atom_parser("abcdefg").parse(concatcp!(Atom::LOOP.0, SAMPLE_STR)) + atom("abcdefg").parse(concatcp!(Atom::LOOP.0, SAMPLE_STR)) ); assert_eq!( Err(nom::Err::Error(Error::new( concatcp!(Atom::LOOP.0, 0u8, SAMPLE_STR), ErrorKind::Char ))), - flat_atom_parser("abcdefg").parse(concatcp!(Atom::LOOP.0, 0u8, SAMPLE_STR)) + atom("abcdefg").parse(concatcp!(Atom::LOOP.0, 0u8, SAMPLE_STR)) ) } @@ -111,7 +106,7 @@ mod flat_atom { fn loop_ends() { assert_eq!( Ok((SAMPLE_STR, FlatAtom::LoopEnds)), - flat_atom_parser("abcdefg").parse(concatcp!(Atom::LOOP.1, SAMPLE_STR)) + atom("abcdefg").parse(concatcp!(Atom::LOOP.1, SAMPLE_STR)) ) } @@ -119,7 +114,7 @@ mod flat_atom { fn tuple_starts() { assert_eq!( Ok((SAMPLE_STR, FlatAtom::TupleStarts)), - flat_atom_parser("abcdefg").parse(concatcp!(Atom::TUPLE.0, SAMPLE_STR)) + atom("abcdefg").parse(concatcp!(Atom::TUPLE.0, SAMPLE_STR)) ) } @@ -127,7 +122,7 @@ mod flat_atom { fn tuple_ends() { assert_eq!( Ok((SAMPLE_STR, FlatAtom::TupleEnds)), - flat_atom_parser("abcdefg").parse(concatcp!(Atom::TUPLE.1, SAMPLE_STR)) + atom("abcdefg").parse(concatcp!(Atom::TUPLE.1, SAMPLE_STR)) ) } @@ -138,7 +133,7 @@ mod flat_atom { SAMPLE_STR, FlatAtom::SlopeStarts(SlopeModifier::Note, FASTEVAL_INSTRUCTION.parse().unwrap()) )), - flat_atom_parser("abcdefg").parse(concatcp!( + atom("abcdefg").parse(concatcp!( Atom::SLOPE.0, SlopeModifier::NOTE, ' ', @@ -153,7 +148,7 @@ mod flat_atom { fn slope_ends() { assert_eq!( Ok((SAMPLE_STR, FlatAtom::SlopeEnds)), - flat_atom_parser("abcdefg").parse(concatcp!(Atom::SLOPE.1, SAMPLE_STR)) + atom("abcdefg").parse(concatcp!(Atom::SLOPE.1, SAMPLE_STR)) ) } @@ -161,7 +156,7 @@ mod flat_atom { fn comment() { assert_eq!( Ok((SAMPLE_STR, FlatAtom::Comment)), - flat_atom_parser("abcdefg").parse(concatcp!( + atom("abcdefg").parse(concatcp!( Atom::COMMENT.0, "hi I'm a little pony", SAMPLE_STR, @@ -175,22 +170,24 @@ mod flat_atom { mod modifier { use std::num::{NonZeroU16, NonZeroU8}; + use const_format::concatcp; + use nom::error::{Error, ErrorKind, VerboseError}; + use super::FLATATOM_SAMPLE_STRING as SAMPLE_STR; - use super::*; - use crate::bng::score::{lex::lexer::Parse, Modifier}; + use crate::bng::score::{modifier, Modifier}; #[test] fn volume() { assert_eq!( Ok((SAMPLE_STR, Modifier::Volume(2))), - Modifier::parse(concatcp!(Modifier::VOLUME, 2u8, SAMPLE_STR)) + modifier::>(concatcp!(Modifier::VOLUME, 2u8, SAMPLE_STR)) ); assert_eq!( Err(nom::Err::Error(Error::new( concatcp!(Modifier::VOLUME, 2556u16, SAMPLE_STR), ErrorKind::Char ))), - Modifier::parse(concatcp!(Modifier::VOLUME, 2556u16, SAMPLE_STR)) + modifier(concatcp!(Modifier::VOLUME, 2556u16, SAMPLE_STR)) ); } @@ -198,14 +195,14 @@ mod modifier { fn octave() { assert_eq!( Ok((SAMPLE_STR, Modifier::Octave(2))), - Modifier::parse(concatcp!(Modifier::OCTAVE, 2u8, SAMPLE_STR)) + modifier::>(concatcp!(Modifier::OCTAVE, 2u8, SAMPLE_STR)) ); assert_eq!( Err(nom::Err::Error(Error::new( concatcp!(Modifier::OCTAVE, 2556u16, SAMPLE_STR), ErrorKind::Char ))), - Modifier::parse(concatcp!(Modifier::OCTAVE, 2556u16, SAMPLE_STR)) + modifier(concatcp!(Modifier::OCTAVE, 2556u16, SAMPLE_STR)) ); } @@ -216,21 +213,21 @@ mod modifier { SAMPLE_STR, Modifier::Length(unsafe { NonZeroU8::new_unchecked(2) }) )), - Modifier::parse(concatcp!(Modifier::LENGTH, 2u8, SAMPLE_STR)) + modifier::>(concatcp!(Modifier::LENGTH, 2u8, SAMPLE_STR)) ); assert_eq!( Err(nom::Err::Error(Error::new( concatcp!(Modifier::LENGTH, 2556u16, SAMPLE_STR), ErrorKind::Char ))), - Modifier::parse(concatcp!(Modifier::LENGTH, 2556u16, SAMPLE_STR)) + modifier(concatcp!(Modifier::LENGTH, 2556u16, SAMPLE_STR)) ); assert_eq!( Err(nom::Err::Error(Error::new( concatcp!(Modifier::LENGTH, 0u8, SAMPLE_STR), ErrorKind::Char ))), - Modifier::parse(concatcp!(Modifier::LENGTH, 0u8, SAMPLE_STR)) + modifier(concatcp!(Modifier::LENGTH, 0u8, SAMPLE_STR)) ); } @@ -241,35 +238,37 @@ mod modifier { SAMPLE_STR, Modifier::Tempo(unsafe { NonZeroU16::new_unchecked(2) }) )), - Modifier::parse(concatcp!(Modifier::TEMPO, 2u8, SAMPLE_STR)) + modifier::>(concatcp!(Modifier::TEMPO, 2u8, SAMPLE_STR)) ); assert_eq!( Err(nom::Err::Error(Error::new( concatcp!(655353u32, SAMPLE_STR), ErrorKind::Digit ))), - Modifier::parse(concatcp!(Modifier::TEMPO, 655353u32, SAMPLE_STR)) + modifier(concatcp!(Modifier::TEMPO, 655353u32, SAMPLE_STR)) ); } } mod quick_modifier { + use const_format::concatcp; + use nom::error::VerboseError; + use super::FLATATOM_SAMPLE_STRING as SAMPLE_STR; - use super::*; use crate::bng::score::{ - lex::{lexer::Parse, DOWN, OFF, ON, UP}, - QuickModifier, + lex::{DOWN, OFF, ON, UP}, + quick_modifier, QuickModifier, }; #[test] fn volume() { assert_eq!( Ok((SAMPLE_STR, QuickModifier::Volume(UP))), - QuickModifier::parse(concatcp!(QuickModifier::VOLUME.0, SAMPLE_STR)) + quick_modifier::>(concatcp!(QuickModifier::VOLUME.0, SAMPLE_STR)) ); assert_eq!( Ok((SAMPLE_STR, QuickModifier::Volume(DOWN))), - QuickModifier::parse(concatcp!(QuickModifier::VOLUME.1, SAMPLE_STR)) + quick_modifier::>(concatcp!(QuickModifier::VOLUME.1, SAMPLE_STR)) ); } @@ -277,11 +276,11 @@ mod quick_modifier { fn octave() { assert_eq!( Ok((SAMPLE_STR, QuickModifier::Octave(UP))), - QuickModifier::parse(concatcp!(QuickModifier::OCTAVE.0, SAMPLE_STR)) + quick_modifier::>(concatcp!(QuickModifier::OCTAVE.0, SAMPLE_STR)) ); assert_eq!( Ok((SAMPLE_STR, QuickModifier::Octave(DOWN))), - QuickModifier::parse(concatcp!(QuickModifier::OCTAVE.1, SAMPLE_STR)) + quick_modifier::>(concatcp!(QuickModifier::OCTAVE.1, SAMPLE_STR)) ); } @@ -289,11 +288,11 @@ mod quick_modifier { fn length() { assert_eq!( Ok((SAMPLE_STR, QuickModifier::Length(UP))), - QuickModifier::parse(concatcp!(QuickModifier::LENGTH.0, SAMPLE_STR)) + quick_modifier::>(concatcp!(QuickModifier::LENGTH.0, SAMPLE_STR)) ); assert_eq!( Ok((SAMPLE_STR, QuickModifier::Length(DOWN))), - QuickModifier::parse(concatcp!(QuickModifier::LENGTH.1, SAMPLE_STR)) + quick_modifier::>(concatcp!(QuickModifier::LENGTH.1, SAMPLE_STR)) ); } @@ -301,20 +300,22 @@ mod quick_modifier { fn pizz() { assert_eq!( Ok((SAMPLE_STR, QuickModifier::Pizz(ON))), - QuickModifier::parse(concatcp!(QuickModifier::PIZZ.0, SAMPLE_STR)) + quick_modifier::>(concatcp!(QuickModifier::PIZZ.0, SAMPLE_STR)) ); assert_eq!( Ok((SAMPLE_STR, QuickModifier::Pizz(OFF))), - QuickModifier::parse(concatcp!(QuickModifier::PIZZ.1, SAMPLE_STR)) + quick_modifier::>(concatcp!(QuickModifier::PIZZ.1, SAMPLE_STR)) ); } } #[cfg(test)] mod slope_modifier { + use const_format::concatcp; + use nom::error::VerboseError; + use super::FLATATOM_FASTEVAL_INSTRUCTION as INSTRUCTION; - use super::*; - use crate::bng::score::{lex::lexer::Parse, Atom, SlopeModifier}; + use crate::bng::score::{slope_modifier, Atom, SlopeModifier}; const SAMPLE_STR: &str = concatcp!(' ', INSTRUCTION, Atom::SLOPE.1); @@ -322,7 +323,7 @@ mod slope_modifier { fn note() { assert_eq!( Ok((SAMPLE_STR, SlopeModifier::Note)), - SlopeModifier::parse(concatcp!(SlopeModifier::NOTE, SAMPLE_STR)) + slope_modifier::>(concatcp!(SlopeModifier::NOTE, SAMPLE_STR)) ) } @@ -330,7 +331,7 @@ mod slope_modifier { fn volume() { assert_eq!( Ok((SAMPLE_STR, SlopeModifier::Volume)), - SlopeModifier::parse(concatcp!(SlopeModifier::VOLUME, SAMPLE_STR)) + slope_modifier::>(concatcp!(SlopeModifier::VOLUME, SAMPLE_STR)) ) } @@ -338,7 +339,7 @@ mod slope_modifier { fn octave() { assert_eq!( Ok((SAMPLE_STR, SlopeModifier::Octave)), - SlopeModifier::parse(concatcp!(SlopeModifier::OCTAVE, SAMPLE_STR)) + slope_modifier::>(concatcp!(SlopeModifier::OCTAVE, SAMPLE_STR)) ) } @@ -346,7 +347,7 @@ mod slope_modifier { fn length() { assert_eq!( Ok((SAMPLE_STR, SlopeModifier::Length)), - SlopeModifier::parse(concatcp!(SlopeModifier::LENGTH, SAMPLE_STR)) + slope_modifier::>(concatcp!(SlopeModifier::LENGTH, SAMPLE_STR)) ) } @@ -354,7 +355,7 @@ mod slope_modifier { fn tempo() { assert_eq!( Ok((SAMPLE_STR, SlopeModifier::Tempo)), - SlopeModifier::parse(concatcp!(SlopeModifier::TEMPO, SAMPLE_STR)) + slope_modifier::>(concatcp!(SlopeModifier::TEMPO, SAMPLE_STR)) ) } }