feat(errors): Replace failure with anyhow crate (#17)

Fixes: #14

BREAKING CHANGE: Result functions now return anyhow::Error
This commit is contained in:
Kat Marchán 2019-10-20 00:25:28 -04:00 committed by GitHub
parent 69d2ac7207
commit ee149a70ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 205 additions and 264 deletions

107
Cargo.lock generated
View File

@ -1,5 +1,10 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "anyhow"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "arrayvec"
version = "0.4.12"
@ -73,26 +78,6 @@ name = "autocfg"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "backtrace"
version = "0.3.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "backtrace-sys"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "base64"
version = "0.10.1"
@ -172,13 +157,13 @@ dependencies = [
name = "cacache"
version = "3.0.0"
dependencies = [
"anyhow 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
"async-attributes 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"async-std 0.99.10 (registry+https://github.com/rust-lang/crates.io-index)",
"chownr 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"chownr 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mkdirp 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -188,8 +173,9 @@ dependencies = [
"serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)",
"sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ssri 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ssri 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -210,10 +196,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chownr"
version = "2.0.0"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"anyhow 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
"nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -351,26 +337,6 @@ name = "either"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "failure"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
"failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "failure_derive"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
@ -833,11 +799,6 @@ dependencies = [
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-demangle"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc_version"
version = "0.2.3"
@ -936,17 +897,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ssri"
version = "4.0.0"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
"sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thiserror 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -959,17 +920,6 @@ dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "synstructure"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempfile"
version = "3.1.0"
@ -991,6 +941,24 @@ dependencies = [
"unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thiserror"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"thiserror-impl 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thiserror-impl"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tinytemplate"
version = "1.0.2"
@ -1082,6 +1050,7 @@ dependencies = [
]
[metadata]
"checksum anyhow 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "26a33395d03a231820d5da1c4c886e3eedd53dda1cb161d8ed1c40f253d80e15"
"checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
"checksum async-attributes 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5266d863e013ece9c8793b69fe6d3a70679f7adea32c92d0aa5eb6e2a55d4d06"
"checksum async-macros 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e421d59b24c1feea2496e409b3e0a8de23e5fc130a2ddc0b012e551f3b272bba"
@ -1089,8 +1058,6 @@ dependencies = [
"checksum async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de6bd58f7b9cc49032559422595c81cbfcf04db2f2133592f70af19e258a1ced"
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
"checksum backtrace 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "690a62be8920ccf773ee00ef0968649b0e724cda8bd5b12286302b4ae955fdf5"
"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b"
"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
@ -1103,7 +1070,7 @@ dependencies = [
"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
"checksum cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)" = "4fc9a35e1f4290eb9e5fc54ba6cf40671ed2a2514c3eeb2b2a908dda2ea5a1be"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum chownr 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "53acee514702cea2b35b2a2ab596fed5a1fbf03bd3800b9a515cf727e41e1dc9"
"checksum chownr 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97905cd65d78952ee4c11e51060b126a2f71e33d4cee0d0574e9381e0e0f0ccb"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394"
@ -1117,8 +1084,6 @@ dependencies = [
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
"checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9"
"checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
@ -1175,7 +1140,6 @@ dependencies = [
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9"
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
@ -1189,11 +1153,12 @@ dependencies = [
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
"checksum ssri 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "39168b592f0fd63cce9e04551a410dd00594f27c12bed3540c09969e53359a30"
"checksum ssri 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c848bd203b24e8fa9512198fb91cafad085e4b43917c0d39c53bd59178d9f17b"
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
"checksum synstructure 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203"
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thiserror 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4d29c937875c7fdf8af9b1edac17ebbe167e342a01072ce53b168c544c8a7608"
"checksum thiserror-impl 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "836d68a4d4b9be617c45ac0b2d3aefbca3c3945947c81365bbb341fffbdccd1b"
"checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20"
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
"checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"

View File

@ -17,7 +17,7 @@ categories = [
maintenance = { status = "actively-developed" }
[dependencies]
ssri = "4.0.0"
ssri = "4.1.0"
hex = "0.3.2"
tempfile = "3.0.8"
sha-1 = "0.8.1"
@ -26,15 +26,16 @@ digest = "0.8.0"
serde_json = "1.0.39"
serde = "1.0.92"
serde_derive = "1.0.92"
failure = "0.1.5"
walkdir = "2.2.7"
either = "1.5.2"
mkdirp = "1.0.0"
futures-preview = "0.3.0-alpha.18"
async-std = { version = "0.99.10", features = ["unstable"]}
anyhow = "1.0.16"
thiserror = "1.0.3"
[target.'cfg(unix)'.dependencies]
chownr = "2.0.0"
chownr = "3.0.0"
nix = "0.14.0"
[dev-dependencies]

View File

@ -3,6 +3,7 @@ use std::path::Path;
use std::pin::Pin;
use std::task::{Context, Poll};
use anyhow::Result;
use async_std;
use futures::prelude::*;
use ssri::{Algorithm, Integrity, IntegrityChecker};
@ -24,8 +25,10 @@ impl std::io::Read for Reader {
}
impl Reader {
pub fn check(self) -> Result<Algorithm, Error> {
self.checker.result().ok_or(Error::IntegrityError)
pub fn check(self) -> Result<Algorithm> {
self.checker
.result()
.ok_or(anyhow::Error::new(Error::IntegrityError))
}
}
@ -47,12 +50,14 @@ impl AsyncRead for AsyncReader {
}
impl AsyncReader {
pub fn check(self) -> Result<Algorithm, Error> {
self.checker.result().ok_or(Error::IntegrityError)
pub fn check(self) -> Result<Algorithm> {
self.checker
.result()
.ok_or(anyhow::Error::new(Error::IntegrityError))
}
}
pub fn open(cache: &Path, sri: Integrity) -> Result<Reader, Error> {
pub fn open(cache: &Path, sri: Integrity) -> Result<Reader> {
let cpath = path::content_path(&cache, &sri);
Ok(Reader {
fd: File::open(cpath)?,
@ -60,7 +65,7 @@ pub fn open(cache: &Path, sri: Integrity) -> Result<Reader, Error> {
})
}
pub async fn open_async(cache: &Path, sri: Integrity) -> Result<AsyncReader, Error> {
pub async fn open_async(cache: &Path, sri: Integrity) -> Result<AsyncReader> {
let cpath = path::content_path(&cache, &sri);
Ok(AsyncReader {
fd: async_std::fs::File::open(cpath).await?,
@ -68,49 +73,45 @@ pub async fn open_async(cache: &Path, sri: Integrity) -> Result<AsyncReader, Err
})
}
pub fn read(cache: &Path, sri: &Integrity) -> Result<Vec<u8>, Error> {
pub fn read(cache: &Path, sri: &Integrity) -> Result<Vec<u8>> {
let cpath = path::content_path(&cache, &sri);
let ret = fs::read(&cpath)?;
if sri.check(&ret).is_some() {
Ok(ret)
} else {
Err(Error::IntegrityError)
Err(Error::IntegrityError)?
}
}
pub async fn read_async<'a>(cache: &'a Path, sri: &'a Integrity) -> Result<Vec<u8>, Error> {
pub async fn read_async<'a>(cache: &'a Path, sri: &'a Integrity) -> Result<Vec<u8>> {
let cpath = path::content_path(&cache, &sri);
let ret = async_std::fs::read(&cpath).await?;
if sri.check(&ret).is_some() {
Ok(ret)
} else {
Err(Error::IntegrityError)
Err(Error::IntegrityError)?
}
}
pub fn copy(cache: &Path, sri: &Integrity, to: &Path) -> Result<u64, Error> {
pub fn copy(cache: &Path, sri: &Integrity, to: &Path) -> Result<u64> {
let cpath = path::content_path(&cache, &sri);
let ret = fs::copy(&cpath, to)?;
let data = fs::read(cpath)?;
if sri.check(data).is_some() {
Ok(ret)
} else {
Err(Error::IntegrityError)
Err(Error::IntegrityError)?
}
}
pub async fn copy_async<'a>(
cache: &'a Path,
sri: &'a Integrity,
to: &'a Path,
) -> Result<u64, Error> {
pub async fn copy_async<'a>(cache: &'a Path, sri: &'a Integrity, to: &'a Path) -> Result<u64> {
let cpath = path::content_path(&cache, &sri);
let ret = async_std::fs::copy(&cpath, to).await?;
let data = async_std::fs::read(cpath).await?;
if sri.check(data).is_some() {
Ok(ret)
} else {
Err(Error::IntegrityError)
Err(Error::IntegrityError)?
}
}

View File

@ -1,18 +1,18 @@
use std::fs;
use std::path::Path;
use anyhow::Result;
use async_std::fs as afs;
use ssri::Integrity;
use crate::content::path;
use crate::errors::Error;
pub fn rm(cache: &Path, sri: &Integrity) -> Result<(), Error> {
pub fn rm(cache: &Path, sri: &Integrity) -> Result<()> {
fs::remove_file(path::content_path(&cache, &sri))?;
Ok(())
}
pub async fn rm_async(cache: &Path, sri: &Integrity) -> Result<(), Error> {
pub async fn rm_async(cache: &Path, sri: &Integrity) -> Result<()> {
afs::remove_file(path::content_path(&cache, &sri)).await?;
Ok(())
}

View File

@ -4,6 +4,7 @@ use std::path::{Path, PathBuf};
use std::pin::Pin;
use std::sync::Mutex;
use anyhow::Result;
use async_std::fs as afs;
use async_std::future::Future;
use async_std::task::{self, Context, JoinHandle, Poll};
@ -13,7 +14,6 @@ use ssri::{Algorithm, Integrity, IntegrityOpts};
use tempfile::NamedTempFile;
use crate::content::path;
use crate::errors::Error;
pub struct Writer {
cache: PathBuf,
@ -22,7 +22,7 @@ pub struct Writer {
}
impl Writer {
pub fn new(cache: &Path, algo: Algorithm) -> Result<Writer, Error> {
pub fn new(cache: &Path, algo: Algorithm) -> Result<Writer> {
let cache_path = cache.to_path_buf();
let mut tmp_path = cache_path.clone();
tmp_path.push("tmp");
@ -34,7 +34,7 @@ impl Writer {
})
}
pub fn close(self) -> Result<Integrity, Error> {
pub fn close(self) -> Result<Integrity> {
let sri = self.builder.result();
let cpath = path::content_path(&self.cache, &sri);
DirBuilder::new()
@ -80,7 +80,7 @@ enum Operation {
impl AsyncWriter {
#[allow(clippy::new_ret_no_self)]
#[allow(clippy::needless_lifetimes)]
pub async fn new(cache: &Path, algo: Algorithm) -> Result<AsyncWriter, Error> {
pub async fn new(cache: &Path, algo: Algorithm) -> Result<AsyncWriter> {
let cache_path = cache.to_path_buf();
let mut tmp_path = cache_path.clone();
tmp_path.push("tmp");
@ -97,7 +97,7 @@ impl AsyncWriter {
})))))
}
pub async fn close(self) -> Result<Integrity, Error> {
pub async fn close(self) -> Result<Integrity> {
// NOTE: How do I even get access to `inner` safely???
// let inner = ???;
// Blocking, but should be a very fast op.
@ -121,12 +121,12 @@ impl AsyncWriter {
// Safe unwrap. cpath always has multiple segments
.create(cpath.parent().unwrap())
.await
.map_err(Error::Io);
.map_err(anyhow::Error::new);
if res.is_err() {
let _ = s.send(res.map(|_| sri));
} else {
let res = tmpfile.persist(cpath);
let res = res.map_err(Error::PersistError);
let res = res.map_err(anyhow::Error::new);
let _ = s.send(res.map(|_| sri));
}
State::Idle(None)
@ -142,7 +142,6 @@ impl AsyncWriter {
})
.map(|opt| opt.ok_or_else(|| io_error("file closed")))
.await?
.map_err(|_| Error::from(io_error("blocking task failed")))
.await?
}
}

View File

@ -1,72 +1,16 @@
use std::io;
#[cfg(unix)]
use chownr;
use failure::Fail;
use serde_json;
use tempfile;
use walkdir;
use thiserror::Error;
/// Error type returned by all API calls.
#[derive(Fail, Debug)]
#[derive(Error, Debug)]
pub enum Error {
/// Returned when an index or content entry could not be found during
/// lookup.
#[fail(display = "not found")]
#[error("not found")]
NotFound,
/// Returned when an integrity check has failed.
#[fail(display = "integrity check failed")]
#[error("integrity check failed")]
IntegrityError,
/// Returned when a size check has failed.
#[fail(display = "size check failed")]
#[error("size check failed")]
SizeError,
/// Returned when there's an std::io::Error.
#[fail(display = "{}", _0)]
Io(#[fail(cause)] io::Error),
/// Returned when there's an error with changing uid/gid on an entry.
#[fail(display = "{}", _0)]
#[cfg(unix)]
Chownr(#[fail(cause)] chownr::Error),
/// Returned when there's an issue with metadata (de)serialization.
#[fail(display = "{}", _0)]
SerdeJson(#[fail(cause)] serde_json::error::Error),
/// Returned when a content entry could not be moved to its final
/// destination.
#[fail(display = "{}", _0)]
PersistError(#[fail(cause)] tempfile::PersistError),
/// Returned when something went wrong while traversing the index during
/// `cacache::ls`.
#[fail(display = "{}", _0)]
WalkDir(#[fail(cause)] walkdir::Error),
}
impl From<std::io::Error> for Error {
fn from(error: std::io::Error) -> Self {
Error::Io(error)
}
}
#[cfg(unix)]
impl From<chownr::Error> for Error {
fn from(error: chownr::Error) -> Self {
Error::Chownr(error)
}
}
impl From<serde_json::error::Error> for Error {
fn from(error: serde_json::error::Error) -> Self {
Error::SerdeJson(error)
}
}
impl From<tempfile::PersistError> for Error {
fn from(error: tempfile::PersistError) -> Self {
Error::PersistError(error)
}
}
impl From<walkdir::Error> for Error {
fn from(error: walkdir::Error) -> Self {
Error::WalkDir(error)
}
}

View File

@ -5,6 +5,7 @@ use std::task::{Context, Poll};
use futures::prelude::*;
use anyhow::Result;
use ssri::{Algorithm, Integrity};
use crate::content::read::{self, AsyncReader, Reader};
@ -42,14 +43,15 @@ impl AsyncGet {
/// ```no_run
/// # use async_std::prelude::*;
/// # use async_std::task;
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # task::block_on(async {
/// # example().await.unwrap();
/// # });
/// # Ok(())
/// # }
/// #
/// # async fn example() -> Result<(), cacache::Error> {
/// # async fn example() -> Result<()> {
/// let mut handle = cacache::get::open("./my-cache", "my-key").await?;
/// let mut str = String::new();
/// handle.read_to_string(&mut str).await?;
@ -58,7 +60,7 @@ impl AsyncGet {
/// # Ok(())
/// # }
/// ```
pub fn check(self) -> Result<Algorithm, Error> {
pub fn check(self) -> Result<Algorithm> {
self.reader.check()
}
}
@ -70,14 +72,15 @@ impl AsyncGet {
/// ```no_run
/// # use async_std::prelude::*;
/// # use async_std::task;
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # task::block_on(async {
/// # example().await.unwrap();
/// # });
/// # Ok(())
/// # }
/// #
/// # async fn example() -> Result<(), cacache::Error> {
/// # async fn example() -> Result<()> {
/// let mut handle = cacache::get::open("./my-cache", "my-key").await?;
/// let mut str = String::new();
/// handle.read_to_string(&mut str).await?;
@ -86,7 +89,7 @@ impl AsyncGet {
/// # Ok(())
/// # }
/// ```
pub async fn open<P, K>(cache: P, key: K) -> Result<AsyncGet, Error>
pub async fn open<P, K>(cache: P, key: K) -> Result<AsyncGet>
where
P: AsRef<Path>,
K: AsRef<str>,
@ -94,7 +97,7 @@ where
if let Some(entry) = index::find_async(cache.as_ref(), key.as_ref()).await? {
open_hash(cache, entry.integrity).await
} else {
Err(Error::NotFound)
Err(Error::NotFound)?
}
}
@ -104,14 +107,15 @@ where
/// ```no_run
/// # use async_std::prelude::*;
/// # use async_std::task;
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # task::block_on(async {
/// # example().await.unwrap();
/// # });
/// # Ok(())
/// # }
/// #
/// # async fn example() -> Result<(), cacache::Error> {
/// # async fn example() -> Result<()> {
/// let sri = cacache::put::data("./my-cache", "key", b"hello world").await?;
/// let mut handle = cacache::get::open_hash("./my-cache", sri).await?;
/// let mut str = String::new();
@ -121,7 +125,7 @@ where
/// # Ok(())
/// # }
/// ```
pub async fn open_hash<P>(cache: P, sri: Integrity) -> Result<AsyncGet, Error>
pub async fn open_hash<P>(cache: P, sri: Integrity) -> Result<AsyncGet>
where
P: AsRef<Path>,
{
@ -137,19 +141,20 @@ where
/// ```no_run
/// # use async_std::prelude::*;
/// # use async_std::task;
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # task::block_on(async {
/// # example().await.unwrap();
/// # });
/// # Ok(())
/// # }
/// #
/// # async fn example() -> Result<(), cacache::Error> {
/// # async fn example() -> Result<()> {
/// let data = cacache::get::data("./my-cache", "my-key").await?;
/// # Ok(())
/// # }
/// ```
pub async fn data<P, K>(cache: P, key: K) -> Result<Vec<u8>, Error>
pub async fn data<P, K>(cache: P, key: K) -> Result<Vec<u8>>
where
P: AsRef<Path>,
K: AsRef<str>,
@ -157,7 +162,7 @@ where
if let Some(entry) = index::find_async(cache.as_ref(), key.as_ref()).await? {
data_hash(cache, &entry.integrity).await
} else {
Err(Error::NotFound)
Err(Error::NotFound)?
}
}
@ -168,20 +173,21 @@ where
/// ```no_run
/// # use async_std::prelude::*;
/// # use async_std::task;
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # task::block_on(async {
/// # example().await.unwrap();
/// # });
/// # Ok(())
/// # }
/// #
/// # async fn example() -> Result<(), cacache::Error> {
/// # async fn example() -> Result<()> {
/// let sri = cacache::put::data("./my-cache", "my-key", b"hello").await?;
/// let data = cacache::get::data_hash("./my-cache", &sri).await?;
/// # Ok(())
/// # }
/// ```
pub async fn data_hash<P>(cache: P, sri: &Integrity) -> Result<Vec<u8>, Error>
pub async fn data_hash<P>(cache: P, sri: &Integrity) -> Result<Vec<u8>>
where
P: AsRef<Path>,
{
@ -194,19 +200,20 @@ where
/// ```no_run
/// # use async_std::prelude::*;
/// # use async_std::task;
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # task::block_on(async {
/// # example().await.unwrap();
/// # });
/// # Ok(())
/// # }
/// #
/// # async fn example() -> Result<(), cacache::Error> {
/// # async fn example() -> Result<()> {
/// cacache::get::copy("./my-cache", "my-key", "./data.txt").await?;
/// # Ok(())
/// # }
/// ```
pub async fn copy<P, K, Q>(cache: P, key: K, to: Q) -> Result<u64, Error>
pub async fn copy<P, K, Q>(cache: P, key: K, to: Q) -> Result<u64>
where
P: AsRef<Path>,
K: AsRef<str>,
@ -215,7 +222,7 @@ where
if let Some(entry) = index::find_async(cache.as_ref(), key.as_ref()).await? {
copy_hash(cache, &entry.integrity, to).await
} else {
Err(Error::NotFound)
Err(Error::NotFound)?
}
}
@ -225,20 +232,21 @@ where
/// ```no_run
/// # use async_std::prelude::*;
/// # use async_std::task;
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # task::block_on(async {
/// # example().await.unwrap();
/// # });
/// # Ok(())
/// # }
/// #
/// # async fn example() -> Result<(), cacache::Error> {
/// # async fn example() -> Result<()> {
/// let sri = cacache::put::data("./my-cache", "my-key", b"hello world").await?;
/// cacache::get::copy_hash("./my-cache", &sri, "./data.txt").await?;
/// # Ok(())
/// # }
/// ```
pub async fn copy_hash<P, Q>(cache: P, sri: &Integrity, to: Q) -> Result<u64, Error>
pub async fn copy_hash<P, Q>(cache: P, sri: &Integrity, to: Q) -> Result<u64>
where
P: AsRef<Path>,
Q: AsRef<Path>,
@ -247,12 +255,12 @@ where
}
/// Gets entry information and metadata for a certain key.
pub async fn entry<P, K>(cache: P, key: K) -> Result<Option<Entry>, Error>
pub async fn entry<P, K>(cache: P, key: K) -> Result<Option<Entry>>
where
P: AsRef<Path>,
K: AsRef<str>,
{
index::find_async(cache.as_ref(), key.as_ref()).await
Ok(index::find_async(cache.as_ref(), key.as_ref()).await?)
}
/// Returns true if the given hash exists in the cache.
@ -288,7 +296,8 @@ impl SyncGet {
///
/// ## Example
/// ```no_run
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # use std::io::Read;
/// let mut handle = cacache::get::open_sync("./my-cache", "my-key")?;
/// let mut str = String::new();
@ -298,7 +307,7 @@ impl SyncGet {
/// # Ok(())
/// # }
/// ```
pub fn check(self) -> Result<Algorithm, Error> {
pub fn check(self) -> Result<Algorithm> {
self.reader.check()
}
}
@ -308,7 +317,8 @@ impl SyncGet {
///
/// ## Example
/// ```no_run
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # use std::io::Read;
/// let mut handle = cacache::get::open_sync("./my-cache", "my-key")?;
/// let mut str = String::new();
@ -318,7 +328,7 @@ impl SyncGet {
/// # Ok(())
/// # }
/// ```
pub fn open_sync<P, K>(cache: P, key: K) -> Result<SyncGet, Error>
pub fn open_sync<P, K>(cache: P, key: K) -> Result<SyncGet>
where
P: AsRef<Path>,
K: AsRef<str>,
@ -326,7 +336,7 @@ where
if let Some(entry) = index::find(cache.as_ref(), key.as_ref())? {
open_hash_sync(cache, entry.integrity)
} else {
Err(Error::NotFound)
Err(Error::NotFound)?
}
}
@ -334,7 +344,8 @@ where
///
/// ## Example
/// ```no_run
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # use std::io::Read;
/// let sri = cacache::put::data_sync("./my-cache", "key", b"hello world")?;
/// let mut handle = cacache::get::open_hash_sync("./my-cache", sri)?;
@ -345,7 +356,7 @@ where
/// # Ok(())
/// # }
/// ```
pub fn open_hash_sync<P>(cache: P, sri: Integrity) -> Result<SyncGet, Error>
pub fn open_hash_sync<P>(cache: P, sri: Integrity) -> Result<SyncGet>
where
P: AsRef<Path>,
{
@ -359,13 +370,14 @@ where
///
/// ## Example
/// ```no_run
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # use std::io::Read;
/// let data = cacache::get::data_sync("./my-cache", "my-key")?;
/// # Ok(())
/// # }
/// ```
pub fn data_sync<P, K>(cache: P, key: K) -> Result<Vec<u8>, Error>
pub fn data_sync<P, K>(cache: P, key: K) -> Result<Vec<u8>>
where
P: AsRef<Path>,
K: AsRef<str>,
@ -373,7 +385,7 @@ where
if let Some(entry) = index::find(cache.as_ref(), key.as_ref())? {
data_hash_sync(cache, &entry.integrity)
} else {
Err(Error::NotFound)
Err(Error::NotFound)?
}
}
@ -382,14 +394,15 @@ where
///
/// ## Example
/// ```no_run
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # use std::io::Read;
/// let sri = cacache::put::data_sync("./my-cache", "my-key", b"hello")?;
/// let data = cacache::get::data_hash_sync("./my-cache", &sri)?;
/// # Ok(())
/// # }
/// ```
pub fn data_hash_sync<P>(cache: P, sri: &Integrity) -> Result<Vec<u8>, Error>
pub fn data_hash_sync<P>(cache: P, sri: &Integrity) -> Result<Vec<u8>>
where
P: AsRef<Path>,
{
@ -400,13 +413,14 @@ where
///
/// ## Example
/// ```no_run
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # use std::io::Read;
/// cacache::get::copy_sync("./my-cache", "my-key", "./my-hello.txt")?;
/// # Ok(())
/// # }
/// ```
pub fn copy_sync<P, K, Q>(cache: P, key: K, to: Q) -> Result<u64, Error>
pub fn copy_sync<P, K, Q>(cache: P, key: K, to: Q) -> Result<u64>
where
P: AsRef<Path>,
K: AsRef<str>,
@ -415,7 +429,7 @@ where
if let Some(entry) = index::find(cache.as_ref(), key.as_ref())? {
copy_hash_sync(cache, &entry.integrity, to)
} else {
Err(Error::NotFound)
Err(Error::NotFound)?
}
}
@ -423,14 +437,15 @@ where
///
/// ## Example
/// ```no_run
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # use std::io::Read;
/// let sri = cacache::put::data_sync("./my-cache", "my-key", b"hello")?;
/// cacache::get::copy_hash_sync("./my-cache", &sri, "./my-hello.txt")?;
/// # Ok(())
/// # }
/// ```
pub fn copy_hash_sync<P, Q>(cache: P, sri: &Integrity, to: Q) -> Result<u64, Error>
pub fn copy_hash_sync<P, Q>(cache: P, sri: &Integrity, to: Q) -> Result<u64>
where
P: AsRef<Path>,
Q: AsRef<Path>,
@ -439,12 +454,12 @@ where
}
/// Gets entry information and metadata for a certain key.
pub fn entry_sync<P, K>(cache: P, key: K) -> Result<Option<Entry>, Error>
pub fn entry_sync<P, K>(cache: P, key: K) -> Result<Option<Entry>>
where
P: AsRef<Path>,
K: AsRef<str>,
{
index::find(cache.as_ref(), key.as_ref())
Ok(index::find(cache.as_ref(), key.as_ref())?)
}
/// Returns true if the given hash exists in the cache.

View File

@ -5,6 +5,7 @@ use std::io::{ErrorKind, Write};
use std::path::{Path, PathBuf};
use std::time::{SystemTime, UNIX_EPOCH};
use anyhow::{Context, Result};
use async_std::{fs as afs, task};
#[cfg(unix)]
use chownr;
@ -20,7 +21,6 @@ use sha2::Sha256;
use ssri::Integrity;
use walkdir::WalkDir;
use crate::errors::Error;
use crate::put::PutOpts;
const INDEX_VERSION: &str = "5";
@ -63,7 +63,7 @@ impl Hash for SerializableEntry {
}
}
pub fn insert(cache: &Path, key: &str, opts: PutOpts) -> Result<Integrity, Error> {
pub fn insert(cache: &Path, key: &str, opts: PutOpts) -> Result<Integrity> {
let bucket = bucket_path(&cache, &key);
#[cfg(unix)]
{
@ -94,11 +94,7 @@ pub fn insert(cache: &Path, key: &str, opts: PutOpts) -> Result<Integrity, Error
.unwrap())
}
pub async fn insert_async<'a>(
cache: &'a Path,
key: &'a str,
opts: PutOpts,
) -> Result<Integrity, Error> {
pub async fn insert_async<'a>(cache: &'a Path, key: &'a str, opts: PutOpts) -> Result<Integrity> {
let bucket = bucket_path(&cache, &key);
let tmpbucket = bucket.clone();
#[cfg(unix)]
@ -107,13 +103,20 @@ pub async fn insert_async<'a>(
let parent = tmpbucket.parent().unwrap();
#[cfg(unix)]
{
if let Some(path) = mkdirp::mkdirp(parent)? {
chownr::chownr(&path, uid, gid)?;
if let Some(path) = mkdirp::mkdirp(parent).with_context(|| {
format!("failed to create index bucket parent dir: {:?}", parent)
})? {
chownr::chownr(&path, uid, gid).with_context(|| {
format!(
"failed to change ownership for path {:?} to {:?}:{:?}",
path, uid, gid
)
})?;
}
}
#[cfg(windows)]
mkdirp::mkdirp(parent)?;
Ok::<(), Error>(())
Ok::<(), anyhow::Error>(())
})
.await?;
let stringified = serde_json::to_string(&SerializableEntry {
@ -141,7 +144,7 @@ pub async fn insert_async<'a>(
.unwrap())
}
pub fn find(cache: &Path, key: &str) -> Result<Option<Entry>, Error> {
pub fn find(cache: &Path, key: &str) -> Result<Option<Entry>> {
let bucket = bucket_path(cache, &key);
Ok(bucket_entries(&bucket)?
.into_iter()
@ -168,7 +171,7 @@ pub fn find(cache: &Path, key: &str) -> Result<Option<Entry>, Error> {
}))
}
pub async fn find_async(cache: &Path, key: &str) -> Result<Option<Entry>, Error> {
pub async fn find_async(cache: &Path, key: &str) -> Result<Option<Entry>> {
let bucket = bucket_path(cache, &key);
Ok(bucket_entries_async(&bucket)
.await?
@ -196,7 +199,7 @@ pub async fn find_async(cache: &Path, key: &str) -> Result<Option<Entry>, Error>
}))
}
pub fn delete(cache: &Path, key: &str) -> Result<(), Error> {
pub fn delete(cache: &Path, key: &str) -> Result<()> {
insert(
cache,
key,
@ -215,7 +218,7 @@ pub fn delete(cache: &Path, key: &str) -> Result<(), Error> {
.map(|_| ())
}
pub async fn delete_async(cache: &Path, key: &str) -> Result<(), Error> {
pub async fn delete_async(cache: &Path, key: &str) -> Result<()> {
insert(
cache,
key,
@ -234,7 +237,7 @@ pub async fn delete_async(cache: &Path, key: &str) -> Result<(), Error> {
.map(|_| ())
}
pub fn ls(cache: &Path) -> impl Iterator<Item = Result<Entry, Error>> {
pub fn ls(cache: &Path) -> impl Iterator<Item = Result<Entry>> {
WalkDir::new(cache.join(format!("index-v{}", INDEX_VERSION)))
.into_iter()
.map(|bucket| {
@ -296,7 +299,7 @@ fn now() -> u128 {
.as_millis()
}
fn bucket_entries(bucket: &Path) -> Result<Vec<SerializableEntry>, Error> {
fn bucket_entries(bucket: &Path) -> Result<Vec<SerializableEntry>> {
use std::io::{BufRead, BufReader};
fs::File::open(bucket)
.map(|file| {
@ -317,12 +320,12 @@ fn bucket_entries(bucket: &Path) -> Result<Vec<SerializableEntry>, Error> {
if err.kind() == ErrorKind::NotFound {
Ok(Vec::new())
} else {
Err(err.into())
Err(err)?
}
})
}
async fn bucket_entries_async(bucket: &Path) -> Result<Vec<SerializableEntry>, Error> {
async fn bucket_entries_async(bucket: &Path) -> Result<Vec<SerializableEntry>> {
use async_std::io::BufReader;
use futures::io::AsyncBufReadExt;
use futures::stream::StreamExt;
@ -499,7 +502,7 @@ mod tests {
let mut entries = ls(&dir)
.map(|x| Ok(x?.key))
.collect::<Result<Vec<_>, Error>>()
.collect::<Result<Vec<_>>>()
.unwrap();
entries.sort();
assert_eq!(entries, vec![String::from("hello"), String::from("world")])

View File

@ -10,9 +10,10 @@
//!
//! ```no_run
//! use async_attributes;
//! use anyhow::Result;
//!
//! #[async_attributes::main]
//! async fn main() -> Result<(), cacache::Error> {
//! async fn main() -> Result<()> {
//! // Data goes in...
//! cacache::put::data("./my-cache", "key", b"hello").await?;
//!
@ -34,9 +35,10 @@
//!
//! ```no_run
//! use async_attributes;
//! use anyhow::Result;
//!
//! #[async_attributes::main]
//! async fn main() -> Result<(), cacache::Error> {
//! async fn main() -> Result<()> {
//! // Data goes in...
//! let sri = cacache::put::data("./my-cache", "key", b"hello").await?;
//!
@ -54,11 +56,12 @@
//! an API reminiscent of `std::fs::OpenOptions`:
//!
//! ```no_run
//! use anyhow::Result;
//! use async_attributes;
//! use async_std::prelude::*;
//!
//! #[async_attributes::main]
//! async fn main() -> Result<(), cacache::Error> {
//! async fn main() -> Result<()> {
//! let mut fd = cacache::put::PutOpts::new().open("./my-cache", "key").await?;
//! for _ in 0..10 {
//! fd.write_all(b"very large data").await?;
@ -85,7 +88,8 @@
//! There are also sync APIs available if you don't want to use async/await:
//!
//! ```no_run
//! fn main() -> Result<(), cacache::Error> {
//! use anyhow::Result;
//! fn main() -> Result<()> {
//! cacache::put::data_sync("./my-cache", "key", b"my-data").unwrap();
//! let data = cacache::get::data_sync("./my-cache", "key").unwrap();
//! assert_eq!(data, b"my-data");

View File

@ -5,6 +5,7 @@ use std::pin::Pin;
use futures::prelude::*;
use anyhow::Result;
#[cfg(unix)]
use nix::unistd::{Gid, Uid};
use serde_json::Value;
@ -22,19 +23,20 @@ use std::task::{Context, Poll};
/// ```no_run
/// # use async_std::prelude::*;
/// # use async_std::task;
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # task::block_on(async {
/// # example().await.unwrap();
/// # });
/// # Ok(())
/// # }
/// #
/// # async fn example() -> Result<(), cacache::Error> {
/// # async fn example() -> Result<()> {
/// cacache::put::data("./my-cache", "my-key", b"hello").await?;
/// # Ok(())
/// # }
/// ```
pub async fn data<P, D, K>(cache: P, key: K, data: D) -> Result<Integrity, Error>
pub async fn data<P, D, K>(cache: P, key: K, data: D) -> Result<Integrity>
where
P: AsRef<Path>,
D: AsRef<[u8]>,
@ -80,7 +82,7 @@ impl AsyncPut {
/// verifies data against `size` and `integrity` options, if provided.
/// Must be called manually in order to complete the writing process,
/// otherwise everything will be thrown out.
pub async fn commit(mut self) -> Result<Integrity, Error> {
pub async fn commit(mut self) -> Result<Integrity> {
let writer_sri = self.writer.close().await?;
if let Some(sri) = &self.opts.sri {
// TODO - ssri should have a .matches method
@ -91,14 +93,14 @@ impl AsyncPut {
.take_while(|h| h.algorithm == algo)
.find(|&h| *h == writer_sri.hashes[0]);
if matched.is_none() {
return Err(Error::IntegrityError);
return Err(Error::IntegrityError)?;
}
} else {
self.opts.sri = Some(writer_sri);
}
if let Some(size) = self.opts.size {
if size != self.written {
return Err(Error::SizeError);
return Err(Error::SizeError)?;
}
}
index::insert_async(&self.cache, &self.key, self.opts).await
@ -109,13 +111,14 @@ impl AsyncPut {
///
/// ## Example
/// ```no_run
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # use std::io::Read;
/// let data = cacache::put::data_sync("./my-cache", "my-key", b"hello")?;
/// # Ok(())
/// # }
/// ```
pub fn data_sync<P, D, K>(cache: P, key: K, data: D) -> Result<Integrity, Error>
pub fn data_sync<P, D, K>(cache: P, key: K, data: D) -> Result<Integrity>
where
P: AsRef<Path>,
D: AsRef<[u8]>,
@ -150,7 +153,7 @@ impl PutOpts {
}
/// Opens the file handle for writing, returning an AsyncPut instance.
pub async fn open<P, K>(self, cache: P, key: K) -> Result<AsyncPut, Error>
pub async fn open<P, K>(self, cache: P, key: K) -> Result<AsyncPut>
where
P: AsRef<Path>,
K: AsRef<str>,
@ -169,7 +172,7 @@ impl PutOpts {
}
/// Opens the file handle for writing synchronously, returning a SyncPut instance.
pub fn open_sync<P, K>(self, cache: P, key: K) -> Result<SyncPut, Error>
pub fn open_sync<P, K>(self, cache: P, key: K) -> Result<SyncPut>
where
P: AsRef<Path>,
K: AsRef<str>,
@ -254,7 +257,7 @@ impl SyncPut {
/// verifies data against `size` and `integrity` options, if provided.
/// Must be called manually in order to complete the writing process,
/// otherwise everything will be thrown out.
pub fn commit(mut self) -> Result<Integrity, Error> {
pub fn commit(mut self) -> Result<Integrity> {
let writer_sri = self.writer.close()?;
if let Some(sri) = &self.opts.sri {
// TODO - ssri should have a .matches method
@ -265,17 +268,17 @@ impl SyncPut {
.take_while(|h| h.algorithm == algo)
.find(|&h| *h == writer_sri.hashes[0]);
if matched.is_none() {
return Err(Error::IntegrityError);
return Err(Error::IntegrityError)?;
}
} else {
self.opts.sri = Some(writer_sri);
}
if let Some(size) = self.opts.size {
if size != self.written {
return Err(Error::SizeError);
return Err(Error::SizeError)?;
}
}
index::insert(&self.cache, &self.key, self.opts)
Ok(index::insert(&self.cache, &self.key, self.opts)?)
}
}

View File

@ -4,10 +4,10 @@ use std::path::Path;
use async_std::fs as afs;
use anyhow::Result;
use ssri::Integrity;
use crate::content::rm;
use crate::errors::Error;
use crate::index;
/// Removes an individual index entry. The associated content will be left
@ -17,14 +17,15 @@ use crate::index;
/// ```no_run
/// # use async_std::prelude::*;
/// # use async_std::task;
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # task::block_on(async {
/// # example().await.unwrap();
/// # });
/// # Ok(())
/// # }
/// #
/// # async fn example() -> Result<(), cacache::Error> {
/// # async fn example() -> Result<()> {
/// let sri = cacache::put::data("./my-cache", "my-key", b"hello").await?;
///
/// cacache::rm::entry("./my-cache", "my-key").await?;
@ -37,8 +38,8 @@ use crate::index;
/// # Ok(())
/// # }
/// ```
pub async fn entry<P: AsRef<Path>>(cache: P, key: &str) -> Result<(), Error> {
index::delete_async(cache.as_ref(), &key).await
pub async fn entry<P: AsRef<Path>>(cache: P, key: &str) -> Result<()> {
Ok(index::delete_async(cache.as_ref(), &key).await?)
}
/// Removes an individual content entry. Any index entries pointing to this
@ -48,14 +49,15 @@ pub async fn entry<P: AsRef<Path>>(cache: P, key: &str) -> Result<(), Error> {
/// ```no_run
/// # use async_std::prelude::*;
/// # use async_std::task;
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # task::block_on(async {
/// # example().await.unwrap();
/// # });
/// # Ok(())
/// # }
/// #
/// # async fn example() -> Result<(), cacache::Error> {
/// # async fn example() -> Result<()> {
/// let sri = cacache::put::data("./my-cache", "my-key", b"hello").await?;
///
/// cacache::rm::entry("./my-cache", "my-key").await?;
@ -69,7 +71,7 @@ pub async fn entry<P: AsRef<Path>>(cache: P, key: &str) -> Result<(), Error> {
/// # Ok(())
/// # }
/// ```
pub async fn content<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<(), Error> {
pub async fn content<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<()> {
rm::rm_async(cache.as_ref(), &sri).await
}
@ -80,14 +82,15 @@ pub async fn content<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<(), Er
/// ```no_run
/// # use async_std::prelude::*;
/// # use async_std::task;
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # task::block_on(async {
/// # example().await.unwrap();
/// # });
/// # Ok(())
/// # }
/// #
/// # async fn example() -> Result<(), cacache::Error> {
/// # async fn example() -> Result<()> {
/// let sri = cacache::put::data("./my-cache", "my-key", b"hello").await?;
///
/// cacache::rm::entry("./my-cache", "my-key").await?;
@ -99,7 +102,7 @@ pub async fn content<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<(), Er
/// # Ok(())
/// # }
/// ```
pub async fn all<P: AsRef<Path>>(cache: P) -> Result<(), Error> {
pub async fn all<P: AsRef<Path>>(cache: P) -> Result<()> {
for entry in cache.as_ref().read_dir()? {
if let Ok(entry) = entry {
afs::remove_dir_all(entry.path()).await?;
@ -113,7 +116,8 @@ pub async fn all<P: AsRef<Path>>(cache: P) -> Result<(), Error> {
///
/// ## Example
/// ```no_run
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # use std::io::Read;
/// let sri = cacache::put::data_sync("./my-cache", "my-key", b"hello")?;
///
@ -127,8 +131,8 @@ pub async fn all<P: AsRef<Path>>(cache: P) -> Result<(), Error> {
/// # Ok(())
/// # }
/// ```
pub fn entry_sync<P: AsRef<Path>>(cache: P, key: &str) -> Result<(), Error> {
index::delete(cache.as_ref(), &key)
pub fn entry_sync<P: AsRef<Path>>(cache: P, key: &str) -> Result<()> {
Ok(index::delete(cache.as_ref(), &key)?)
}
/// Removes an individual content entry synchronously. Any index entries
@ -136,7 +140,8 @@ pub fn entry_sync<P: AsRef<Path>>(cache: P, key: &str) -> Result<(), Error> {
///
/// ## Example
/// ```no_run
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # use std::io::Read;
/// let sri = cacache::put::data_sync("./my-cache", "my-key", b"hello")?;
///
@ -151,7 +156,7 @@ pub fn entry_sync<P: AsRef<Path>>(cache: P, key: &str) -> Result<(), Error> {
/// # Ok(())
/// # }
/// ```
pub fn content_sync<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<(), Error> {
pub fn content_sync<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<()> {
rm::rm(cache.as_ref(), &sri)
}
@ -160,7 +165,8 @@ pub fn content_sync<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<(), Err
///
/// ## Example
/// ```no_run
/// # fn main() -> Result<(), cacache::Error> {
/// # use anyhow::Result;
/// # fn main() -> Result<()> {
/// # use std::io::Read;
/// let sri = cacache::put::data_sync("./my-cache", "my-key", b"hello")?;
///
@ -173,7 +179,7 @@ pub fn content_sync<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<(), Err
/// # Ok(())
/// # }
/// ```
pub fn all_sync<P: AsRef<Path>>(cache: P) -> Result<(), Error> {
pub fn all_sync<P: AsRef<Path>>(cache: P) -> Result<()> {
for entry in cache.as_ref().read_dir()? {
if let Ok(entry) = entry {
fs::remove_dir_all(entry.path())?;