#![doc = include_str!("../README.md")]
use std::{
fs,
io::{self, BufReader, BufWriter, Seek, Write},
path,
};
mod errors;
mod utils;
pub use errors::*;
pub const SAMPLE_RATE: u32 = 202860;
pub fn encode(file: impl AsRef<path::Path>, wav_output: impl AsRef<path::Path>) -> Result<()> {
let file = fs::File::open(file)?;
utils::check_file_size(&file)?;
let str_path = wav_output.as_ref().display().to_string();
let wav_output = if !str_path.ends_with(".wav") {
format!("{}.wav", wav_output.as_ref().display())
} else {
str_path
};
let mut reader = BufReader::new(&file);
let mut writer = BufWriter::new(fs::File::create(wav_output)?);
writer.write_all(&utils::create_wav_header(file.metadata()?.len() as u32))?;
io::copy(&mut reader, &mut writer)?;
Ok(())
}
pub fn decode(file: impl AsRef<path::Path>, output: impl AsRef<path::Path>) -> Result<()> {
let output_file = fs::File::open(&file)?;
utils::check_file_size(&output_file)?;
utils::check_wav_file_size(&output_file)?;
let mut reader = BufReader::new(output_file);
let mut writer = BufWriter::new(fs::File::create(output)?);
reader.seek(std::io::SeekFrom::Start(44))?;
io::copy(&mut reader, &mut writer)?;
Ok(())
}
pub fn encode_bytes(bytes: &[u8]) -> Result<Vec<u8>> {
if bytes.len() > 4294967295 {
return Err(Error::LargeFileSize);
}
let mut wav_bytes = utils::create_wav_header(bytes.len() as u32).to_vec();
wav_bytes.extend_from_slice(bytes);
Ok(wav_bytes)
}
pub fn decode_bytes(bytes: &[u8]) -> Result<Vec<u8>> {
if bytes.len() < 44 {
return Err(Error::InvalidWavFile(
"the minimum wav file size is 44 bytes".to_string(),
));
}
Ok(bytes[44..].to_vec())
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs;
#[test]
fn test_encode_decode() {
fs::write("test.txt", "Some context").unwrap();
encode("test.txt", "test.wav").unwrap();
decode("test.wav", "test2.txt").unwrap();
let file = fs::File::open("test.txt").unwrap();
let file2 = fs::File::open("test2.txt").unwrap();
assert_eq!(
fs::read_to_string("test.txt").unwrap(),
fs::read_to_string("test2.txt").unwrap()
);
assert_eq!(
file.metadata().unwrap().len(),
file2.metadata().unwrap().len()
);
fs::remove_file("test.txt").unwrap();
fs::remove_file("test2.txt").unwrap();
fs::remove_file("test.wav").unwrap();
}
}