diff --git a/Cargo.lock b/Cargo.lock index 0ca6d78..c1497ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,6 +21,11 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "anyhow" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "arrayvec" version = "0.4.12" @@ -380,6 +385,7 @@ dependencies = [ name = "thinp" version = "0.1.0" dependencies = [ + "anyhow 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)", "crc32c 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -393,6 +399,25 @@ dependencies = [ "quickcheck 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "quickcheck_macros 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thiserror" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "thiserror-impl 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -456,6 +481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" "checksum aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum anyhow 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" @@ -501,6 +527,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum syn 1.0.30 (registry+https://github.com/rust-lang/crates.io-index)" = "93a56fabc59dce20fe48b6c832cc249c713e7ed88fa28b0ee0a3bfcaae5fe4e2" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" +"checksum thiserror-impl 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" "checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" diff --git a/Cargo.toml b/Cargo.toml index e1e1c7c..fc98546 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2018" license = "GPL3" [dependencies] +anyhow = "1.0" byteorder = "1.3" clap = "2.33" crc32c = "0.4" @@ -14,9 +15,10 @@ libc = "0.2.71" nix = "0.17" nom = "5.1" num_cpus = "1.13" -rand = "0.7" -num-traits = "0.2" num-derive = "0.3" +num-traits = "0.2" +rand = "0.7" +thiserror = "1.0" [dev-dependencies] quickcheck = "0.9" diff --git a/src/pack/node_encode.rs b/src/pack/node_encode.rs index c5e8370..a8a54a6 100644 --- a/src/pack/node_encode.rs +++ b/src/pack/node_encode.rs @@ -1,3 +1,4 @@ +use thiserror::Error; use std::{io, io::Write}; use nom::{bytes::complete::*, number::complete::*, IResult}; @@ -6,41 +7,27 @@ use crate::pack::vm::*; //------------------------------------------- -#[derive(Debug)] +#[derive(Error, Debug)] pub enum PackError { + #[error("Couldn't parse binary data")] ParseError, - IOError, -} -impl std::error::Error for PackError {} + #[error("Write error")] + WriteError { source: std::io::Error }, +} pub type PResult = Result; fn nom_to_pr(r: IResult<&[u8], T>) -> PResult<(&[u8], T)> { - match r { - Ok(v) => Ok(v), - Err(_) => Err(PackError::ParseError), - } + r.map_err(|_source| PackError::ParseError) } fn io_to_pr(r: io::Result) -> PResult { - match r { - Ok(v) => Ok(v), - Err(_) => Err(PackError::IOError), - } + r.map_err(|source| PackError::WriteError {source}) } //------------------------------------------- -impl std::fmt::Display for PackError { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - PackError::ParseError => write!(f, "parse error"), - PackError::IOError => write!(f, "IO error"), - } - } -} - fn run64(i: &[u8], count: usize) -> IResult<&[u8], Vec> { let (i, ns) = nom::multi::many_m_n(count, count, le_u64)(i)?; Ok((i, ns)) diff --git a/src/pack/toplevel.rs b/src/pack/toplevel.rs index bd1757d..97f5eb7 100644 --- a/src/pack/toplevel.rs +++ b/src/pack/toplevel.rs @@ -1,3 +1,4 @@ +use anyhow::{anyhow, Context, Result}; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use flate2::{read::ZlibDecoder, write::ZlibEncoder, Compression}; @@ -67,8 +68,8 @@ fn mk_chunk_vecs(nr_blocks: u64, nr_jobs: u64) -> Vec> { vs } -pub fn pack(input_file: &str, output_file: &str) -> Result<(), Box> { - let nr_blocks = get_nr_blocks(&input_file)?; +pub fn pack(input_file: &str, output_file: &str) -> Result<()> { + let nr_blocks = get_nr_blocks(&input_file).context("getting nr blocks")?; let nr_jobs = std::cmp::max(1, std::cmp::min(num_cpus::get() as u64, nr_blocks / 128)); let chunk_vecs = mk_chunk_vecs(nr_blocks, nr_jobs); @@ -85,7 +86,7 @@ pub fn pack(input_file: &str, output_file: &str) -> Result<(), Box> { .truncate(true) .open(output_file)?; - write_header(&output, nr_blocks)?; + write_header(&output, nr_blocks).context("unable to write pack file header")?; let sync_input = Arc::new(Mutex::new(input)); let sync_output = Arc::new(Mutex::new(output)); @@ -108,7 +109,7 @@ fn crunch( input: Arc>, output: Arc>, ranges: Vec<(u64, u64)>, -) -> io::Result<()> +) -> Result<()> where R: Read + Seek, W: Write, @@ -128,7 +129,7 @@ where let kind = metadata_block_type(data); if kind != BT::UNKNOWN { z.write_u64::(b)?; - pack_block(&mut z, kind, &data); + pack_block(&mut z, kind, &data)?; written += 1; if written == 1024 { @@ -242,22 +243,18 @@ fn metadata_block_type(buf: &[u8]) -> BT { } } -fn check(r: &PResult) { - match r { - Ok(_) => {} - Err(PackError::ParseError) => panic!("parse error"), - Err(PackError::IOError) => panic!("io error"), - } -} - -fn pack_block(w: &mut W, kind: BT, buf: &[u8]) { +fn pack_block(w: &mut W, kind: BT, buf: &[u8]) -> Result<()> { match kind { - BT::SUPERBLOCK => check(&pack_superblock(w, buf)), - BT::NODE => check(&pack_btree_node(w, buf)), - BT::INDEX => check(&pack_index(w, buf)), - BT::BITMAP => check(&pack_bitmap(w, buf)), - BT::UNKNOWN => {panic!("asked to pack an unknown block type")} + BT::SUPERBLOCK => pack_superblock(w, buf).context("unable to pack superblock")?, + BT::NODE => pack_btree_node(w, buf).context("unable to pack btree node")?, + BT::INDEX => pack_index(w, buf).context("unable to pack space map index")?, + BT::BITMAP => pack_bitmap(w, buf).context("unable to pack space map bitmap")?, + BT::UNKNOWN => { + return Err(anyhow!("asked to pack an unknown block type")) + } } + + Ok(()) } fn write_zero_block(w: &mut W, b: u64) -> io::Result<()>