Add error handling for unsupported audio formats

This commit is contained in:
Simon Bruder 2020-06-24 23:50:19 +02:00
parent 8afe245e05
commit e921a150e1
No known key found for this signature in database
GPG key ID: 6F03E0000CC5B62F
3 changed files with 39 additions and 7 deletions

21
Cargo.lock generated
View file

@ -65,6 +65,7 @@ dependencies = [
"num-derive", "num-derive",
"num-traits", "num-traits",
"pretty_env_logger", "pretty_env_logger",
"thiserror",
"zip", "zip",
] ]
@ -441,6 +442,26 @@ dependencies = [
"unicode-width", "unicode-width",
] ]
[[package]]
name = "thiserror"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "thread_local" name = "thread_local"
version = "1.0.1" version = "1.0.1"

View file

@ -7,10 +7,11 @@ edition = "2018"
[dependencies] [dependencies]
anyhow = "1.0.31" anyhow = "1.0.31"
byteorder = "1.3.4" byteorder = "1.3.4"
clap = "3.0.0-beta.1"
log = "0.4.8" log = "0.4.8"
nom = "5.1.1" nom = "5.1.1"
num-derive = "0.3" num-derive = "0.3"
num-traits = "0.2" num-traits = "0.2"
pretty_env_logger = "0.4" pretty_env_logger = "0.4"
thiserror = "1.0.20"
zip = { version = "0.5.5", default-features = false, features = ["deflate"] } zip = { version = "0.5.5", default-features = false, features = ["deflate"] }
clap = "3.0.0-beta.1"

View file

@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::TryInto; use std::convert::TryInto;
use anyhow::{anyhow, Result}; use anyhow::Result;
use log::{debug, info, warn}; use log::{debug, info, warn};
use nom::bytes::complete::tag; use nom::bytes::complete::tag;
use nom::error::ParseError; use nom::error::ParseError;
@ -10,13 +10,20 @@ use nom::number::complete::{le_i32, le_u32};
use nom::{take_str, IResult}; use nom::{take_str, IResult};
use num_derive::FromPrimitive; use num_derive::FromPrimitive;
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
use thiserror::Error;
use crate::utils; use crate::utils;
use crate::utils::exec_nom_parser; use crate::utils::exec_nom_parser;
use crate::xact3::adpcm; use crate::xact3::adpcm;
#[derive(Error, Debug)]
pub enum Error {
#[error("{0:?} is not a supported format")]
UnsupportedFormat(FormatTag),
}
#[derive(Clone, FromPrimitive, Debug, PartialEq)] #[derive(Clone, FromPrimitive, Debug, PartialEq)]
enum FormatTag { pub enum FormatTag {
PCM = 0, PCM = 0,
XMA = 1, XMA = 1,
ADPCM = 2, ADPCM = 2,
@ -43,11 +50,11 @@ impl From<u32> for Format {
} }
impl TryInto<adpcm::WaveFormat> for Format { impl TryInto<adpcm::WaveFormat> for Format {
type Error = anyhow::Error; type Error = Error;
fn try_into(self) -> Result<adpcm::WaveFormat> { fn try_into(self) -> Result<adpcm::WaveFormat, Error> {
if self.tag != FormatTag::ADPCM { if self.tag != FormatTag::ADPCM {
return Err(anyhow!("Format is not ADPCM")); return Err(Error::UnsupportedFormat(self.tag));
} }
let n_block_align = (self.alignment as u16 + 22) * self.channels; let n_block_align = (self.alignment as u16 + 22) * self.channels;
@ -236,6 +243,9 @@ pub struct Sound<'a> {
impl Sound<'_> { impl Sound<'_> {
pub fn to_wav(&self) -> Result<Vec<u8>> { pub fn to_wav(&self) -> Result<Vec<u8>> {
adpcm::build_wav(self.format.clone().try_into()?, self.data) match &self.format.tag {
FormatTag::ADPCM => adpcm::build_wav(self.format.clone().try_into()?, self.data),
_ => Err(Error::UnsupportedFormat(self.format.tag.clone()).into()),
}
} }
} }