Skip to content
Snippets Groups Projects
Commit 7237c2b7 authored by tnias's avatar tnias
Browse files

initial commit

parents
No related branches found
No related tags found
No related merge requests found
/target/
**/*.rs.bk
Cargo.lock
[package]
name = "drumchallenge"
version = "0.1.0"
authors = ["Phil <phil@grmr.de>"]
[dependencies]
nom = "3.2"
Rust implementation of [golang challenge #1](https://golang-challenge.org/go-challenge1).
A simple binary fileformat for a drum machine is given. The task is to reverse
it and implement a decoder it.
File added
File added
File added
File added
File added
#[macro_use]
extern crate nom;
pub mod parser;
use std::fmt;
#[derive(Debug)]
pub struct Pattern {
size: u64,
version: String,
tempo: f32,
lines: Vec<Line>,
}
#[derive(Debug)]
pub struct Line {
id: u8,
name: String,
data: Vec<u8>,
}
impl fmt::Display for Pattern {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut lines = String::new();
for line in &self.lines {
lines += format!("{}\n", line).as_str();
}
write!(f, "Saved with HW Version: {}\nTempo: {}\n{}",
self.version, self.tempo, lines)
}
}
impl fmt::Display for Line {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut fancy = String::new();
for (i,x) in self.data.iter().enumerate() {
fancy += format!(
"{}{}",
if i%4 == 0 { "|" } else {""},
match *x { 0 => "-", 1 => "x", _ => "?" }
).as_str();
}
write!(f, "({}) {}\t{}|", self.id, self.name, fancy)
}
}
use nom::*;
use super::{Pattern, Line};
named!(parse_line<&[u8], Line>,
do_parse!(
id: be_u8 >>
namelen: be_u32 >>
name: take_str!(namelen) >>
data: take!(16) >>
(
Line {
id: id,
name: name.to_string(),
data: data.to_vec(),
}
)
)
);
named!(parse_pattern<&[u8], Pattern>,
do_parse!(
tag!(b"SPLICE") >>
size: be_u64 >>
version: take_str!(32) >>
tempo: le_f32 >>
// TODO: make sure we do not parse more than we are supposed to do
// limit ourselves by `size`
lines: many0!(parse_line) >>
(
Pattern{
size: size,
version: version.trim_matches('\u{0}').to_string(),
tempo: tempo,
lines: lines,
}
)
)
);
pub fn parse(i: &[u8]) -> IResult<&[u8], Pattern> {
parse_pattern(i)
}
/* - - - - - - - */
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {}
#[test]
fn test_fixtures() {
// TODO: implement(port) table based test
let b = include_bytes!("../fixtures/pattern_1.splice");
match parse_pattern(b) {
IResult::Done(_, p) => {
println!("{}", p);
panic!("yes.")
},
_ => panic!("nope.")
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment