Use nom to parse instrument data.
This commit is contained in:
parent
209d1db66e
commit
99eb9f048f
25
Cargo.lock
generated
25
Cargo.lock
generated
|
@ -2,6 +2,31 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slamshuffle"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
|
|
@ -7,3 +7,4 @@ license = "MIT"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nom = "7"
|
||||
|
|
58
src/instruments.rs
Normal file
58
src/instruments.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use nom::{
|
||||
bytes::complete::tag_no_case,
|
||||
character::complete::{hex_digit1, line_ending, not_line_ending, space1},
|
||||
combinator::{map_parser, map_res, opt},
|
||||
error::{Error, ErrorKind},
|
||||
multi::fold_many0,
|
||||
sequence::{preceded, separated_pair, terminated},
|
||||
IResult,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct InstrumentSet([u8; 32]);
|
||||
|
||||
impl InstrumentSet {
|
||||
pub fn generate(input: &str) -> Self {
|
||||
match Self::parse(input) {
|
||||
Ok((_, set)) => set,
|
||||
Err(_) => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse<'i>(input: &'i str) -> IResult<&'i str, Self> {
|
||||
fold_many0(
|
||||
terminated(
|
||||
opt(preceded(
|
||||
tag_no_case("#WAVE"),
|
||||
map_parser(not_line_ending, wave_numbers),
|
||||
)),
|
||||
line_ending,
|
||||
),
|
||||
Self::default,
|
||||
|mut set, bytes: Option<(usize, u8)>| match bytes {
|
||||
Some((slot, sample)) => {
|
||||
let pos = slot - 0x20;
|
||||
set.0[pos] = sample;
|
||||
set
|
||||
}
|
||||
None => set,
|
||||
},
|
||||
)(input)
|
||||
}
|
||||
}
|
||||
|
||||
fn wave_numbers(input: &str) -> IResult<&str, (usize, u8)> {
|
||||
separated_pair(
|
||||
map_res(hex_digit1, |s: &str| {
|
||||
s.parse::<usize>().map_err(|_| nom::error::make_error::<&str, Error<&str>>(s, ErrorKind::HexDigit)).and_then(|n| {
|
||||
if (0x20..0x30).contains(&n) {
|
||||
Ok(n)
|
||||
} else {
|
||||
Err(nom::error::make_error(s, ErrorKind::MapRes))
|
||||
}
|
||||
})
|
||||
}),
|
||||
space1,
|
||||
map_res(hex_digit1, |s: &str| s.parse::<u8>()),
|
||||
)(input)
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
pub mod instruments;
|
||||
pub mod mfvi;
|
||||
|
|
Loading…
Reference in a new issue