Skip to content

Commit

Permalink
to_split: big error rework
Browse files Browse the repository at this point in the history
  • Loading branch information
gwen-lg committed May 11, 2024
1 parent 6121c6d commit 83a7c6f
Show file tree
Hide file tree
Showing 10 changed files with 255 additions and 175 deletions.
7 changes: 3 additions & 4 deletions src/content/area.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::Size;
use crate::SubError;
use super::{ContentError, Size};

/// Location at which to display the subtitle.
#[derive(Debug, Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -53,7 +52,7 @@ impl Area {
}

impl TryFrom<AreaValues> for Area {
type Error = SubError;
type Error = ContentError;

fn try_from(coords_value: AreaValues) -> Result<Self, Self::Error> {
// Check for weird bounding boxes. Ideally we
Expand All @@ -63,7 +62,7 @@ impl TryFrom<AreaValues> for Area {
// have non-negative width and height and we'll
// crash if they don't.
if coords_value.x2 <= coords_value.x1 || coords_value.y2 <= coords_value.y1 {
Err(SubError::Parse("invalid bounding box".into()))
Err(Self::Error::InvalidAreaBounding)
} else {
Ok(Self(coords_value))
}
Expand Down
10 changes: 10 additions & 0 deletions src/content/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,13 @@ mod size;

pub use area::{Area, AreaValues};
pub use size::Size;
use thiserror::Error;

/// Error for content
#[derive(Debug, Error)]
pub enum ContentError {
/// Indicate an invalid bounding box Area
/// Example: If at least one coordinate value of second point are inferior of first point.
#[error("Invalid bounding box for Area")]
InvalidAreaBounding,
}
33 changes: 3 additions & 30 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,13 @@
//! Custom error types.
use std::io;
use std::path::PathBuf;
use thiserror::Error;

/// A type representing errors that are specific to `subtile`. Note that we may
/// normally return `Error`, not `SubError`, which allows to return other
/// kinds of errors from third-party libraries.
#[derive(Debug, Error)]
pub enum SubError {
/// Our input data ended sooner than we expected.
#[error("Input ended unexpectedly")]
IncompleteInput,

/// We were unable to find a required key in an `*.idx` file.
#[error("Could not find required key '{0}'")]
MissingKey(&'static str),

/// We could not parse a value.
#[error("Could not parse: {0}")]
Parse(String),

/// We could not process a subtitle image.
#[error("Could not process subtitle image: {0}")]
Image(String),

/// We have leftover input that we didn't expect.
#[error("Unexpected extra input")]
UnexpectedInput,

/// We could not read a file.
#[error("Could not read '{path}'")]
Io {
/// Source error
source: io::Error,
/// Path of the file we tried to read
path: PathBuf,
},
/// Error with `VobSub`
#[error("Error with VobSub")]
VobSub(#[from] crate::vobsub::VobSubError),
}
24 changes: 13 additions & 11 deletions src/vobsub/idx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ use std::io::prelude::*;
use std::io::BufReader;
use std::path::Path;

use super::{palette, sub, Palette};
use crate::errors::SubError;
use crate::vobsub::IResultExt;
use super::{palette, sub, IResultExt, Palette, VobSubError};

/// A `*.idx` file describing the subtitles in a `*.sub` file.
#[derive(Debug)]
Expand All @@ -27,9 +25,9 @@ pub struct Index {
impl Index {
/// Open an `*.idx` file and the associated `*.sub` file.
#[profiling::function]
pub fn open<P: AsRef<Path>>(path: P) -> Result<Index, SubError> {
pub fn open<P: AsRef<Path>>(path: P) -> Result<Index, VobSubError> {
let path = path.as_ref();
let mkerr_idx = |source| SubError::Io {
let mkerr_idx = |source| VobSubError::Io {
source,
path: path.into(),
};
Expand All @@ -42,13 +40,13 @@ impl Index {
sub_path.set_extension("sub");

let sub_path = sub_path.as_path();
let mut sub = fs::File::open(sub_path).map_err(|source| SubError::Io {
let mut sub = fs::File::open(sub_path).map_err(|source| VobSubError::Io {
source,
path: sub_path.into(),
})?;
let mut sub_data = vec![];
sub.read_to_end(&mut sub_data)
.map_err(|source| SubError::Io {
.map_err(|source| VobSubError::Io {
source,
path: sub_path.into(),
})?;
Expand Down Expand Up @@ -77,10 +75,10 @@ impl Index {

/// Read the palette in .idx file content
#[profiling::function]
pub fn read_palette<T, Err>(mut input: BufReader<T>, mkerr: &Err) -> Result<Palette, SubError>
pub fn read_palette<T, Err>(mut input: BufReader<T>, mkerr: &Err) -> Result<Palette, VobSubError>
where
T: std::io::Read,
Err: Fn(io::Error) -> SubError,
Err: Fn(io::Error) -> VobSubError,
{
static KEY_VALUE: Lazy<Regex> = Lazy::new(|| Regex::new("^([A-Za-z/ ]+): (.*)").unwrap());

Expand All @@ -93,15 +91,19 @@ where
let val = cap.get(2).unwrap().as_str();
match key {
"palette" => {
palette_val = Some(palette(val.as_bytes()).to_vobsub_result()?);
palette_val = Some(
palette(val.as_bytes())
.to_result_no_rest()
.map_err(VobSubError::PaletteError)?,
);
}
_ => trace!("Unimplemented idx key: {}", key),
}
}
buf.clear();
}

let palette = palette_val.ok_or(SubError::MissingKey("palette"))?;
let palette = palette_val.ok_or(VobSubError::MissingKey("palette"))?;
Ok(palette)
}

Expand Down
17 changes: 9 additions & 8 deletions src/vobsub/img.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use nom::{
};
use safemem::write_bytes;

use crate::{content::Size, util::BytesFormatter, SubError};
use super::VobSubError;
use crate::{content::Size, util::BytesFormatter};

/// A run-length encoded value.
#[derive(Debug)]
Expand Down Expand Up @@ -47,7 +48,7 @@ fn rle(input: (&[u8], usize)) -> IResult<(&[u8], usize), Rle> {

/// Decompress the scan-line `input` into `output`, returning the number of
/// input bytes consumed.
fn scan_line(input: &[u8], output: &mut [u8]) -> Result<usize, SubError> {
fn scan_line(input: &[u8], output: &mut [u8]) -> Result<usize, VobSubError> {
trace!("scan line starting with {:?}", BytesFormatter(input));
let width = output.len();
let mut x = 0;
Expand All @@ -63,33 +64,33 @@ fn scan_line(input: &[u8], output: &mut [u8]) -> Result<usize, SubError> {
cast::usize(run.cnt)
};
if x + count > output.len() {
return Err(SubError::Image("scan line is too long".into()));
return Err(VobSubError::Image("scan line is too long".into()));
}
write_bytes(&mut output[x..x + count], run.val);
x += count;
}
IResult::Err(err) => match err {
nom::Err::Incomplete(needed) => {
return Err(SubError::Image(format!(
return Err(VobSubError::Image(format!(
"not enough bytes parsing subtitle scan \
line: {needed:?}"
)));
}
nom::Err::Error(err) => {
return Err(SubError::Image(format!(
return Err(VobSubError::Image(format!(
"error parsing subtitle scan line: {err:?}"
)));
}
nom::Err::Failure(err) => {
return Err(SubError::Image(format!(
return Err(VobSubError::Image(format!(
"Failure parsing subtitle scan line: {err:?}"
)));
}
},
}
}
if x > width {
return Err(SubError::Image("decoded scan line is too long".into()));
return Err(VobSubError::Image("decoded scan line is too long".into()));
}
// Round up to the next full byte.
if pos.1 > 0 {
Expand All @@ -102,7 +103,7 @@ fn scan_line(input: &[u8], output: &mut [u8]) -> Result<usize, SubError> {
/// order, starting at the upper-left and scanning right and down, with one
/// byte for each 2-bit value.
#[profiling::function]
pub fn decompress(size: Size, data: [&[u8]; 2]) -> Result<Vec<u8>, SubError> {
pub fn decompress(size: Size, data: [&[u8]; 2]) -> Result<Vec<u8>, VobSubError> {
trace!(
"decompressing image {:?}, max: [0x{:x}, 0x{:x}]",
&size,
Expand Down
Loading

0 comments on commit 83a7c6f

Please sign in to comment.