context & function names without another Parse trait
This commit is contained in:
parent
78d7c493bb
commit
a2566f1be3
6 changed files with 192 additions and 104 deletions
|
@ -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"] }
|
||||
|
|
|
@ -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<S: ToString> 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()
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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::<D, _>(&sheet, flat_atom_parser(¬es))
|
||||
atom_mapper::<D, _>(&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<Atoms, <D as Deserializer<'de>>::Error>
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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::<VerboseError<&str>>(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::<VerboseError<&str>>(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::<VerboseError<&str>>(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::<VerboseError<&str>>(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::<VerboseError<&str>>(concatcp!(QuickModifier::VOLUME.0, SAMPLE_STR))
|
||||
);
|
||||
assert_eq!(
|
||||
Ok((SAMPLE_STR, QuickModifier::Volume(DOWN))),
|
||||
QuickModifier::parse(concatcp!(QuickModifier::VOLUME.1, SAMPLE_STR))
|
||||
quick_modifier::<VerboseError<&str>>(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::<VerboseError<&str>>(concatcp!(QuickModifier::OCTAVE.0, SAMPLE_STR))
|
||||
);
|
||||
assert_eq!(
|
||||
Ok((SAMPLE_STR, QuickModifier::Octave(DOWN))),
|
||||
QuickModifier::parse(concatcp!(QuickModifier::OCTAVE.1, SAMPLE_STR))
|
||||
quick_modifier::<VerboseError<&str>>(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::<VerboseError<&str>>(concatcp!(QuickModifier::LENGTH.0, SAMPLE_STR))
|
||||
);
|
||||
assert_eq!(
|
||||
Ok((SAMPLE_STR, QuickModifier::Length(DOWN))),
|
||||
QuickModifier::parse(concatcp!(QuickModifier::LENGTH.1, SAMPLE_STR))
|
||||
quick_modifier::<VerboseError<&str>>(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::<VerboseError<&str>>(concatcp!(QuickModifier::PIZZ.0, SAMPLE_STR))
|
||||
);
|
||||
assert_eq!(
|
||||
Ok((SAMPLE_STR, QuickModifier::Pizz(OFF))),
|
||||
QuickModifier::parse(concatcp!(QuickModifier::PIZZ.1, SAMPLE_STR))
|
||||
quick_modifier::<VerboseError<&str>>(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::<VerboseError<&str>>(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::<VerboseError<&str>>(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::<VerboseError<&str>>(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::<VerboseError<&str>>(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::<VerboseError<&str>>(concatcp!(SlopeModifier::TEMPO, SAMPLE_STR))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue