use std::fmt;
use std::str::FromStr;
use num::FromPrimitive;
use crate::errors::ParseError;
#[derive(Copy, Clone, Debug, FromPrimitive, PartialEq)]
#[repr(u8)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum SampleSet {
Default = 0,
Normal = 1,
Soft = 2,
Drum = 3,
}
bitflags! {
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug)]
#[allow(non_upper_case_globals)]
pub struct Additions: u32 {
const WHISTLE = 1 << 1;
const FINISH = 1 << 2;
const CLAP = 1 << 3;
}
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SampleInfo {
pub sample_set: SampleSet,
pub addition_set: SampleSet,
pub custom_index: i32,
pub sample_volume: i32,
pub filename: String,
}
impl Default for SampleInfo {
fn default() -> SampleInfo {
SampleInfo {
sample_set: SampleSet::Default,
addition_set: SampleSet::Default,
custom_index: 0,
sample_volume: 0,
filename: "".to_owned(),
}
}
}
impl FromStr for SampleInfo {
type Err = ParseError;
fn from_str(line: &str) -> Result<SampleInfo, Self::Err> {
let extra_parts = line.split(':').collect::<Vec<_>>();
let sample_set = extra_parts[0].parse::<u32>()?;
let addition_set = extra_parts[1].parse::<u32>()?;
let custom_index = match extra_parts.get(2) {
Some(v) => v.parse::<i32>()?,
None => 0,
};
let sample_volume = match extra_parts.get(3) {
Some(v) => v.parse::<i32>()?,
None => 0,
};
let filename = match extra_parts.get(4) {
Some(v) => (*v).to_owned(),
None => String::new(),
};
Ok(SampleInfo {
addition_set: SampleSet::from_u32(addition_set)
.ok_or(ParseError::InvalidSampleSet(addition_set))?,
sample_set: SampleSet::from_u32(sample_set)
.ok_or(ParseError::InvalidSampleSet(sample_set))?,
custom_index,
sample_volume,
filename,
})
}
}
impl fmt::Display for SampleInfo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}:{}:{}:{}:{}",
self.sample_set as u32,
self.addition_set as u32,
self.custom_index,
self.sample_volume,
self.filename
)
}
}