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 amplify::{From, Wrapper};
|
||||||
use derive_new::new;
|
use derive_new::new;
|
||||||
use derived_deref::Deref;
|
use derived_deref::Deref;
|
||||||
use fasteval::Instruction;
|
use fasteval::{Compiler, Instruction};
|
||||||
pub(super) use instrument::Instrument;
|
pub(super) use instrument::Instrument;
|
||||||
pub(super) use score::Atom;
|
pub(super) use score::Atom;
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use serde::{de::Visitor, Deserialize};
|
||||||
|
|
||||||
mod instrument;
|
mod instrument;
|
||||||
mod score;
|
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)]
|
#[derive(new)]
|
||||||
#[cfg_attr(debug_assertions, derive(Serialize))]
|
#[cfg_attr(debug_assertions, derive(Serialize))]
|
||||||
pub(super) struct Channel {
|
pub(super) struct Channel {
|
||||||
|
|
|
@ -65,19 +65,9 @@ fn flat_atom_parser(notes: &str) -> impl Parser<&str, FlatAtom, nom::error::Erro
|
||||||
separated_pair(
|
separated_pair(
|
||||||
SlopeModifier::parse,
|
SlopeModifier::parse,
|
||||||
char(' '),
|
char(' '),
|
||||||
map_res(take_till1(|c| c == ','), |s| {
|
map_res(take_till1(|c| c == ','), |s: &str| {
|
||||||
let parser = fasteval::Parser::new();
|
s.parse()
|
||||||
let mut slab = fasteval::Slab::new();
|
.map_err(|_| nom::error::Error::new(s, nom::error::ErrorKind::Verify))
|
||||||
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(),
|
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -136,19 +136,7 @@ mod flat_atom {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Ok((
|
Ok((
|
||||||
SAMPLE_STR,
|
SAMPLE_STR,
|
||||||
FlatAtom::SlopeStarts(
|
FlatAtom::SlopeStarts(SlopeModifier::Note, FASTEVAL_INSTRUCTION.parse().unwrap())
|
||||||
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()
|
|
||||||
)
|
|
||||||
)),
|
)),
|
||||||
flat_atom_parser("abcdefg").parse(concatcp!(
|
flat_atom_parser("abcdefg").parse(concatcp!(
|
||||||
Atom::SLOPE.0,
|
Atom::SLOPE.0,
|
||||||
|
|
|
@ -8,14 +8,7 @@ mod inflate {
|
||||||
const FASTEVAL_INSTRUCTION: &str = "1-cos((PI*x)/2)";
|
const FASTEVAL_INSTRUCTION: &str = "1-cos((PI*x)/2)";
|
||||||
|
|
||||||
fn instruction() -> Instruction {
|
fn instruction() -> Instruction {
|
||||||
let parser = fasteval::Parser::new();
|
FASTEVAL_INSTRUCTION.parse().unwrap()
|
||||||
let mut slab = fasteval::Slab::new();
|
|
||||||
parser
|
|
||||||
.parse(FASTEVAL_INSTRUCTION, &mut slab.ps)
|
|
||||||
.unwrap()
|
|
||||||
.from(&slab.ps)
|
|
||||||
.compile(&slab.ps, &mut slab.cs)
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
15
src/main.rs
15
src/main.rs
|
@ -18,12 +18,12 @@ fn main() -> Result<(), serde_yml::Error> {
|
||||||
vec![HashMap::from([
|
vec![HashMap::from([
|
||||||
(
|
(
|
||||||
"sine".to_string(),
|
"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(),
|
"square".to_string(),
|
||||||
Instrument::new(
|
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)]))
|
Some(HashMap::from([("v".to_string(), 1f32)]))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -38,14 +38,3 @@ fn main() -> Result<(), serde_yml::Error> {
|
||||||
println!("{:?}", args);
|
println!("{:?}", args);
|
||||||
Ok(())
|
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