deserialize and parse expression from str
This commit is contained in:
parent
6a04f7da9a
commit
9c6f76fd6e
5 changed files with 48 additions and 49 deletions
43
src/bng.rs
43
src/bng.rs
|
@ -1,13 +1,14 @@
|
|||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use amplify::{From, Wrapper};
|
||||
use derive_new::new;
|
||||
use derived_deref::Deref;
|
||||
use fasteval::Instruction;
|
||||
use fasteval::{Compiler, Instruction};
|
||||
pub(super) use instrument::Instrument;
|
||||
pub(super) use score::Atom;
|
||||
#[cfg(debug_assertions)]
|
||||
use serde::Serialize;
|
||||
use serde::{de::Visitor, Deserialize};
|
||||
|
||||
mod instrument;
|
||||
mod score;
|
||||
|
@ -26,6 +27,44 @@ impl Serialize for Expression {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Expression {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_str(ExpressionVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExpressionVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for ExpressionVisitor {
|
||||
type Value = Expression;
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
formatter
|
||||
.write_str("a math expression following fasteval syntax (https://docs.rs/fasteval)")
|
||||
}
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
v.parse().map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Expression {
|
||||
type Err = fasteval::Error;
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let parser = fasteval::Parser::new();
|
||||
let mut slab = fasteval::Slab::new();
|
||||
Ok(parser
|
||||
.parse(s, &mut slab.ps)?
|
||||
.from(&slab.ps)
|
||||
.compile(&slab.ps, &mut slab.cs)
|
||||
.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(new)]
|
||||
#[cfg_attr(debug_assertions, derive(Serialize))]
|
||||
pub(super) struct Channel {
|
||||
|
|
|
@ -65,19 +65,9 @@ fn flat_atom_parser(notes: &str) -> impl Parser<&str, FlatAtom, nom::error::Erro
|
|||
separated_pair(
|
||||
SlopeModifier::parse,
|
||||
char(' '),
|
||||
map_res(take_till1(|c| c == ','), |s| {
|
||||
let parser = fasteval::Parser::new();
|
||||
let mut slab = fasteval::Slab::new();
|
||||
Result::<Instruction, nom::error::Error<&str>>::Ok(
|
||||
parser
|
||||
.parse(s, &mut slab.ps)
|
||||
.map_err(|_| {
|
||||
nom::error::Error::new(s, nom::error::ErrorKind::Verify)
|
||||
})?
|
||||
.from(&slab.ps)
|
||||
.compile(&slab.ps, &mut slab.cs)
|
||||
.into(),
|
||||
)
|
||||
map_res(take_till1(|c| c == ','), |s: &str| {
|
||||
s.parse()
|
||||
.map_err(|_| nom::error::Error::new(s, nom::error::ErrorKind::Verify))
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -136,19 +136,7 @@ mod flat_atom {
|
|||
assert_eq!(
|
||||
Ok((
|
||||
SAMPLE_STR,
|
||||
FlatAtom::SlopeStarts(
|
||||
SlopeModifier::Note,
|
||||
{
|
||||
let parser = fasteval::Parser::new();
|
||||
let mut slab = fasteval::Slab::new();
|
||||
parser
|
||||
.parse(FASTEVAL_INSTRUCTION, &mut slab.ps)
|
||||
.unwrap()
|
||||
.from(&slab.ps)
|
||||
.compile(&slab.ps, &mut slab.cs)
|
||||
}
|
||||
.into()
|
||||
)
|
||||
FlatAtom::SlopeStarts(SlopeModifier::Note, FASTEVAL_INSTRUCTION.parse().unwrap())
|
||||
)),
|
||||
flat_atom_parser("abcdefg").parse(concatcp!(
|
||||
Atom::SLOPE.0,
|
||||
|
|
|
@ -8,14 +8,7 @@ mod inflate {
|
|||
const FASTEVAL_INSTRUCTION: &str = "1-cos((PI*x)/2)";
|
||||
|
||||
fn instruction() -> Instruction {
|
||||
let parser = fasteval::Parser::new();
|
||||
let mut slab = fasteval::Slab::new();
|
||||
parser
|
||||
.parse(FASTEVAL_INSTRUCTION, &mut slab.ps)
|
||||
.unwrap()
|
||||
.from(&slab.ps)
|
||||
.compile(&slab.ps, &mut slab.cs)
|
||||
.into()
|
||||
FASTEVAL_INSTRUCTION.parse().unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
15
src/main.rs
15
src/main.rs
|
@ -18,12 +18,12 @@ fn main() -> Result<(), serde_yml::Error> {
|
|||
vec![HashMap::from([
|
||||
(
|
||||
"sine".to_string(),
|
||||
Instrument::new(instruction("sin(2*PI*f*t)"), None)
|
||||
Instrument::new("sin(2*PI*f*t)".parse().unwrap(), None)
|
||||
),
|
||||
(
|
||||
"square".to_string(),
|
||||
Instrument::new(
|
||||
instruction("v*abs(sin(2*PI*f*t))"),
|
||||
"v*abs(sin(2*PI*f*t))".parse().unwrap(),
|
||||
Some(HashMap::from([("v".to_string(), 1f32)]))
|
||||
)
|
||||
)
|
||||
|
@ -38,14 +38,3 @@ fn main() -> Result<(), serde_yml::Error> {
|
|||
println!("{:?}", args);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn instruction(expr_str: &str) -> Expression {
|
||||
let parser = fasteval::Parser::new();
|
||||
let mut slab = fasteval::Slab::new();
|
||||
parser
|
||||
.parse(expr_str, &mut slab.ps)
|
||||
.unwrap()
|
||||
.from(&slab.ps)
|
||||
.compile(&slab.ps, &mut slab.cs)
|
||||
.into()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue