deserialize and parse expression from str

This commit is contained in:
Breval Ferrari 2024-10-30 17:50:13 -04:00
parent 6a04f7da9a
commit 9c6f76fd6e
No known key found for this signature in database
GPG key ID: 6FED68D87C479A59
5 changed files with 48 additions and 49 deletions

View file

@ -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 {

View file

@ -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))
}),
),
),

View file

@ -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,

View file

@ -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]

View file

@ -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()
}