1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
mod bin;
pub mod ext;
mod package;
mod transaction;

pub use bin::*;
pub use package::*;
pub use transaction::*;

use std::io;
use std::path::{Path, PathBuf};

use error_chain::error_chain;
use pkgar_core::{Entry, Mode};
//use thiserror::Error;
use user_error::UFE;

const READ_WRITE_HASH_BUF_SIZE: usize = 4 * 1024 * 1024;

error_chain! {
    types {
        Error, ErrorKind, ResultExt;
    }
    
    links {
        Keys(pkgar_keys::Error, pkgar_keys::ErrorKind);
    }
    
    foreign_links {
        Io(io::Error);
    }
    
    errors {
        Core(src: pkgar_core::Error) {
            display("{}", src),
        }
        
        FailedCommit(changed: usize, remaining: usize) {
            display(
                "Failed to commit transaction. {} files changed, {} files remaining",
                changed,
                remaining,
            ),
        }
        
        InvalidPathComponent(path: PathBuf) {
            display("Invalid path component: {}", path.display()),
        }
        
        LengthMismatch(actual: u64, expected: u64) {
            display("Entry size mismatch: expected {}, got {}", expected, actual),
        }
        
        InvalidModeKind(mode: Mode) {
            display("Invalid Mode Kind: {:#o}", mode),
        }
        
        Path(path: PathBuf) {
            display("Path: {}", path.display()),
        }
        
        Entry(entry: Entry) {
            display("Entry: {:?}", entry),
        }
    }
}

impl UFE for Error {}

// Allow .chain_err(|| path )
impl From<&Path> for ErrorKind {
    fn from(path: &Path) -> ErrorKind {
        ErrorKind::Path(path.to_path_buf())
    }
}

impl From<&PathBuf> for ErrorKind {
    fn from(path: &PathBuf) -> ErrorKind {
        ErrorKind::Path(path.clone())
    }
}

// Unfortunately error_chain does not handle types that don't implement
// std::error::Error very well.
impl From<pkgar_core::Error> for Error {
    fn from(err: pkgar_core::Error) -> Error {
        Error::from_kind(ErrorKind::Core(err))
    }
}

/*
// Apparently this conflicts with the first implementation; Just use map_err
// with Error::from for chaining errors to a pkgar_core Result.
impl<T> ResultExt<T> for Result<T, pkgar_core::Error> {
    fn chain_err<F, EK>(self, callback: F) -> Result<T, Error>
        where F: FnOnce() -> EK,
              EK: Into<ErrorKind>,
    {
        self.map_err(|e|
            Error::with_boxed_chain(Box::new(e), callback().into())
        )
    }
}*/