mirror of https://github.com/zkat/cacache-rs.git
feat(errors): remove anyhow and use custom error types (#24)
Co-authored-by: Florian Albertz <git@albertz.io> BREAKING CHANGE: This changes the exported error type(s) for cacache, making it way easier to do error handling when something goes kaput.
This commit is contained in:
parent
88a76189fc
commit
bb815f5f22
|
|
@ -29,7 +29,6 @@ serde_derive = "1.0.102"
|
|||
walkdir = "2.2.9"
|
||||
either = "1.5.3"
|
||||
async-std = { version = "1.0.1", features = ["unstable"] }
|
||||
anyhow = "1.0.19"
|
||||
thiserror = "1.0.5"
|
||||
futures = "0.3.1"
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ 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};
|
||||
|
||||
use crate::content::path;
|
||||
use crate::errors::{Internal, Result};
|
||||
|
||||
pub struct Reader {
|
||||
fd: File,
|
||||
|
|
@ -55,7 +55,7 @@ impl AsyncReader {
|
|||
pub fn open(cache: &Path, sri: Integrity) -> Result<Reader> {
|
||||
let cpath = path::content_path(&cache, &sri);
|
||||
Ok(Reader {
|
||||
fd: File::open(cpath)?,
|
||||
fd: File::open(cpath).to_internal()?,
|
||||
checker: IntegrityChecker::new(sri),
|
||||
})
|
||||
}
|
||||
|
|
@ -63,37 +63,37 @@ pub fn open(cache: &Path, sri: Integrity) -> Result<Reader> {
|
|||
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?,
|
||||
fd: async_std::fs::File::open(cpath).await.to_internal()?,
|
||||
checker: IntegrityChecker::new(sri),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn read(cache: &Path, sri: &Integrity) -> Result<Vec<u8>> {
|
||||
let cpath = path::content_path(&cache, &sri);
|
||||
let ret = fs::read(&cpath)?;
|
||||
let ret = fs::read(&cpath).to_internal()?;
|
||||
sri.check(&ret)?;
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
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?;
|
||||
let ret = async_std::fs::read(&cpath).await.to_internal()?;
|
||||
sri.check(&ret)?;
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
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)?;
|
||||
let ret = fs::copy(&cpath, to).to_internal()?;
|
||||
let data = fs::read(cpath).to_internal()?;
|
||||
sri.check(data)?;
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
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?;
|
||||
let ret = async_std::fs::copy(&cpath, to).await.to_internal()?;
|
||||
let data = async_std::fs::read(cpath).await.to_internal()?;
|
||||
sri.check(data)?;
|
||||
Ok(ret)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
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::{Internal, Result};
|
||||
|
||||
pub fn rm(cache: &Path, sri: &Integrity) -> Result<()> {
|
||||
fs::remove_file(path::content_path(&cache, &sri))?;
|
||||
fs::remove_file(path::content_path(&cache, &sri)).to_internal()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn rm_async(cache: &Path, sri: &Integrity) -> Result<()> {
|
||||
afs::remove_file(path::content_path(&cache, &sri)).await?;
|
||||
afs::remove_file(path::content_path(&cache, &sri))
|
||||
.await
|
||||
.to_internal()?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ 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};
|
||||
|
|
@ -14,6 +13,7 @@ use ssri::{Algorithm, Integrity, IntegrityOpts};
|
|||
use tempfile::NamedTempFile;
|
||||
|
||||
use crate::content::path;
|
||||
use crate::errors::{Internal, Result};
|
||||
|
||||
pub struct Writer {
|
||||
cache: PathBuf,
|
||||
|
|
@ -26,11 +26,14 @@ impl Writer {
|
|||
let cache_path = cache.to_path_buf();
|
||||
let mut tmp_path = cache_path.clone();
|
||||
tmp_path.push("tmp");
|
||||
DirBuilder::new().recursive(true).create(&tmp_path)?;
|
||||
DirBuilder::new()
|
||||
.recursive(true)
|
||||
.create(&tmp_path)
|
||||
.to_internal()?;
|
||||
Ok(Writer {
|
||||
cache: cache_path,
|
||||
builder: IntegrityOpts::new().algorithm(algo),
|
||||
tmpfile: NamedTempFile::new_in(tmp_path)?,
|
||||
tmpfile: NamedTempFile::new_in(tmp_path).to_internal()?,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -40,8 +43,9 @@ impl Writer {
|
|||
DirBuilder::new()
|
||||
.recursive(true)
|
||||
// Safe unwrap. cpath always has multiple segments
|
||||
.create(cpath.parent().unwrap())?;
|
||||
self.tmpfile.persist(cpath)?;
|
||||
.create(cpath.parent().unwrap())
|
||||
.to_internal()?;
|
||||
self.tmpfile.persist(cpath).to_internal()?;
|
||||
Ok(sri)
|
||||
}
|
||||
}
|
||||
|
|
@ -87,11 +91,14 @@ impl AsyncWriter {
|
|||
afs::DirBuilder::new()
|
||||
.recursive(true)
|
||||
.create(&tmp_path)
|
||||
.await?;
|
||||
.await
|
||||
.to_internal()?;
|
||||
Ok(AsyncWriter(Mutex::new(State::Idle(Some(Inner {
|
||||
cache: cache_path,
|
||||
builder: IntegrityOpts::new().algorithm(algo),
|
||||
tmpfile: task::spawn_blocking(|| NamedTempFile::new_in(tmp_path)).await?,
|
||||
tmpfile: task::spawn_blocking(|| NamedTempFile::new_in(tmp_path))
|
||||
.await
|
||||
.to_internal()?,
|
||||
buf: vec![],
|
||||
last_op: None,
|
||||
})))))
|
||||
|
|
@ -101,7 +108,7 @@ impl AsyncWriter {
|
|||
// NOTE: How do I even get access to `inner` safely???
|
||||
// let inner = ???;
|
||||
// Blocking, but should be a very fast op.
|
||||
futures::future::poll_fn(|cx| {
|
||||
Ok(futures::future::poll_fn(|cx| {
|
||||
let state = &mut *self.0.lock().unwrap();
|
||||
|
||||
loop {
|
||||
|
|
@ -121,12 +128,18 @@ impl AsyncWriter {
|
|||
// Safe unwrap. cpath always has multiple segments
|
||||
.create(cpath.parent().unwrap())
|
||||
.await
|
||||
.map_err(anyhow::Error::new);
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"building directory {} failed",
|
||||
cpath.parent().unwrap().display()
|
||||
)
|
||||
});
|
||||
if res.is_err() {
|
||||
let _ = s.send(res.map(|_| sri));
|
||||
} else {
|
||||
let res = tmpfile.persist(cpath);
|
||||
let res = res.map_err(anyhow::Error::new);
|
||||
let res = tmpfile.persist(cpath).with_context(|| {
|
||||
String::from("persisting tempfile failed")
|
||||
});
|
||||
let _ = s.send(res.map(|_| sri));
|
||||
}
|
||||
State::Idle(None)
|
||||
|
|
@ -141,8 +154,10 @@ impl AsyncWriter {
|
|||
}
|
||||
})
|
||||
.map(|opt| opt.ok_or_else(|| io_error("file closed")))
|
||||
.await?
|
||||
.await?
|
||||
.await
|
||||
.to_internal()?
|
||||
.await
|
||||
.to_internal()??)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,35 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use ssri::Integrity;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
#[error("{source}\n\n {}", context.join("\n "))]
|
||||
pub struct InternalError {
|
||||
source: Box<dyn std::error::Error + Send + Sync>,
|
||||
context: Vec<String>,
|
||||
}
|
||||
|
||||
pub trait Internal<T> {
|
||||
fn to_internal(self) -> InternalResult<T>;
|
||||
fn with_context<F: FnOnce() -> String>(self, f: F) -> InternalResult<T>;
|
||||
}
|
||||
|
||||
impl<T, E: 'static + std::error::Error + Send + Sync> Internal<T> for std::result::Result<T, E> {
|
||||
fn to_internal(self) -> InternalResult<T> {
|
||||
self.map_err(|e| InternalError {
|
||||
source: Box::new(e),
|
||||
context: Vec::new(),
|
||||
})
|
||||
}
|
||||
|
||||
fn with_context<F: FnOnce() -> String>(self, f: F) -> InternalResult<T> {
|
||||
self.map_err(|e| InternalError {
|
||||
source: Box::new(e),
|
||||
context: vec![f()],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Error type returned by all API calls.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error {
|
||||
|
|
@ -10,10 +37,29 @@ pub enum Error {
|
|||
/// lookup.
|
||||
#[error("Entry not found for key {1:?} in cache {0:?}")]
|
||||
EntryNotFound(PathBuf, String),
|
||||
/// Returned when an integrity check has failed.
|
||||
#[error("Integrity check failed.\n\tWanted: {0}\n\tActual: {1}")]
|
||||
IntegrityError(Integrity, Integrity),
|
||||
|
||||
/// Returned when a size check has failed.
|
||||
#[error("Size check failed.\n\tWanted: {0}\n\tActual: {1}")]
|
||||
SizeError(usize, usize),
|
||||
|
||||
/// Returned when an integrity check has failed.
|
||||
#[error(transparent)]
|
||||
IntegrityError {
|
||||
#[from]
|
||||
/// The underlying error
|
||||
source: ssri::Error,
|
||||
},
|
||||
|
||||
/// Returned if an internal (e.g. io) operation has failed.
|
||||
#[error(transparent)]
|
||||
InternalError {
|
||||
#[from]
|
||||
/// The underlying error
|
||||
source: InternalError,
|
||||
},
|
||||
}
|
||||
|
||||
/// The result type returned by calls to this library
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
pub type InternalResult<T> = std::result::Result<T, InternalError>;
|
||||
|
|
|
|||
208
src/get.rs
208
src/get.rs
|
|
@ -5,11 +5,10 @@ use std::task::{Context as TaskContext, Poll};
|
|||
|
||||
use futures::prelude::*;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use ssri::{Algorithm, Integrity};
|
||||
|
||||
use crate::content::read;
|
||||
use crate::errors::Error;
|
||||
use crate::errors::{Error, Result};
|
||||
use crate::index::{self, Metadata};
|
||||
|
||||
// ---------
|
||||
|
|
@ -47,22 +46,19 @@ impl Reader {
|
|||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// let mut fd = cacache::Reader::open("./my-cache", "my-key").await?;
|
||||
/// let mut str = String::new();
|
||||
/// fd.read_to_string(&mut str).await?;
|
||||
/// fd.read_to_string(&mut str).await.expect("Failed to read to string");
|
||||
/// // Remember to check that the data you got was correct!
|
||||
/// fd.check()?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub fn check(self) -> Result<Algorithm> {
|
||||
self.reader
|
||||
.check()
|
||||
.context("Cache read data verification check failed.")
|
||||
self.reader.check()
|
||||
}
|
||||
/// Opens a new file handle into the cache, looking it up in the index using
|
||||
/// `key`.
|
||||
|
|
@ -71,13 +67,12 @@ impl Reader {
|
|||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// let mut fd = cacache::Reader::open("./my-cache", "my-key").await?;
|
||||
/// let mut str = String::new();
|
||||
/// fd.read_to_string(&mut str).await?;
|
||||
/// fd.read_to_string(&mut str).await.expect("Failed to read to string");
|
||||
/// // Remember to check that the data you got was correct!
|
||||
/// fd.check()?;
|
||||
/// Ok(())
|
||||
|
|
@ -104,14 +99,13 @@ impl Reader {
|
|||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write("./my-cache", "key", b"hello world").await?;
|
||||
/// let mut fd = cacache::Reader::open_hash("./my-cache", sri).await?;
|
||||
/// let mut str = String::new();
|
||||
/// fd.read_to_string(&mut str).await?;
|
||||
/// fd.read_to_string(&mut str).await.expect("Failed to read to string");
|
||||
/// // Remember to check that the data you got was correct!
|
||||
/// fd.check()?;
|
||||
/// Ok(())
|
||||
|
|
@ -134,10 +128,9 @@ impl Reader {
|
|||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// let data: Vec<u8> = cacache::read("./my-cache", "my-key").await?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
|
|
@ -157,36 +150,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Reads the entire contents of a cache file into a string, looking the
|
||||
/// data up by key.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// let str: String = cacache::read_to_string("./my-cache", "my-key").await?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub async fn read_to_string<P, K>(cache: P, key: K) -> Result<String>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
K: AsRef<str>,
|
||||
{
|
||||
if let Some(entry) = index::find_async(cache.as_ref(), key.as_ref()).await? {
|
||||
read_hash_to_string(cache, &entry.integrity).await
|
||||
} else {
|
||||
Err(Error::EntryNotFound(
|
||||
cache.as_ref().to_path_buf(),
|
||||
key.as_ref().into(),
|
||||
))?
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads the entire contents of a cache file into a bytes vector, looking the
|
||||
/// data up by its content address.
|
||||
///
|
||||
|
|
@ -194,10 +157,9 @@ where
|
|||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write("./my-cache", "my-key", b"hello").await?;
|
||||
/// let data: Vec<u8> = cacache::read_hash("./my-cache", &sri).await?;
|
||||
/// Ok(())
|
||||
|
|
@ -210,31 +172,6 @@ where
|
|||
Ok(read::read_async(cache.as_ref(), sri).await?)
|
||||
}
|
||||
|
||||
/// Reads the entire contents of a cache file into a string, looking the
|
||||
/// data up by its content address.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// let sri = cacache::write("./my-cache", "my-key", b"hello").await?;
|
||||
/// let str: String = cacache::read_hash_to_string("./my-cache", &sri).await?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub async fn read_hash_to_string<P>(cache: P, sri: &Integrity) -> Result<String>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
Ok(String::from_utf8(
|
||||
read::read_async(cache.as_ref(), sri).await?,
|
||||
)?)
|
||||
}
|
||||
|
||||
/// Copies cache data to a specified location. Returns the number of bytes
|
||||
/// copied.
|
||||
///
|
||||
|
|
@ -242,10 +179,9 @@ where
|
|||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// cacache::copy("./my-cache", "my-key", "./data.txt").await?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
|
|
@ -273,10 +209,9 @@ where
|
|||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write("./my-cache", "my-key", b"hello world").await?;
|
||||
/// cacache::copy_hash("./my-cache", &sri, "./data.txt").await?;
|
||||
/// Ok(())
|
||||
|
|
@ -336,22 +271,19 @@ impl SyncReader {
|
|||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> cacache::Result<()> {
|
||||
/// let mut fd = cacache::SyncReader::open("./my-cache", "my-key")?;
|
||||
/// let mut str = String::new();
|
||||
/// fd.read_to_string(&mut str)?;
|
||||
/// fd.read_to_string(&mut str).expect("Failed to read to string");
|
||||
/// // Remember to check that the data you got was correct!
|
||||
/// fd.check()?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub fn check(self) -> Result<Algorithm> {
|
||||
self.reader
|
||||
.check()
|
||||
.context("Cache read data verification check failed.")
|
||||
self.reader.check()
|
||||
}
|
||||
|
||||
/// Opens a new synchronous file handle into the cache, looking it up in the
|
||||
|
|
@ -359,13 +291,12 @@ impl SyncReader {
|
|||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> cacache::Result<()> {
|
||||
/// let mut fd = cacache::SyncReader::open("./my-cache", "my-key")?;
|
||||
/// let mut str = String::new();
|
||||
/// fd.read_to_string(&mut str)?;
|
||||
/// fd.read_to_string(&mut str).expect("Failed to parse string");
|
||||
/// // Remember to check that the data you got was correct!
|
||||
/// fd.check()?;
|
||||
/// Ok(())
|
||||
|
|
@ -390,14 +321,13 @@ impl SyncReader {
|
|||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write_sync("./my-cache", "key", b"hello world")?;
|
||||
/// let mut fd = cacache::SyncReader::open_hash("./my-cache", sri)?;
|
||||
/// let mut str = String::new();
|
||||
/// fd.read_to_string(&mut str)?;
|
||||
/// fd.read_to_string(&mut str).expect("Failed to read to string");
|
||||
/// // Remember to check that the data you got was correct!
|
||||
/// fd.check()?;
|
||||
/// Ok(())
|
||||
|
|
@ -418,10 +348,9 @@ impl SyncReader {
|
|||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> cacache::Result<()> {
|
||||
/// let data = cacache::read_sync("./my-cache", "my-key")?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
|
|
@ -441,42 +370,14 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Reads the entire contents of a cache file synchronously into a string,
|
||||
/// looking the data up by key.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// let str: String = cacache::read_to_string_sync("./my-cache", "my-key")?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read_to_string_sync<P, K>(cache: P, key: K) -> Result<String>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
K: AsRef<str>,
|
||||
{
|
||||
if let Some(entry) = index::find(cache.as_ref(), key.as_ref())? {
|
||||
read_hash_to_string_sync(cache, &entry.integrity)
|
||||
} else {
|
||||
Err(Error::EntryNotFound(
|
||||
cache.as_ref().to_path_buf(),
|
||||
key.as_ref().into(),
|
||||
))?
|
||||
}
|
||||
}
|
||||
/// Reads the entire contents of a cache file synchronously into a bytes
|
||||
/// vector, looking the data up by its content address.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write_sync("./my-cache", "my-key", b"hello")?;
|
||||
/// let data = cacache::read_hash_sync("./my-cache", &sri)?;
|
||||
/// Ok(())
|
||||
|
|
@ -489,36 +390,14 @@ where
|
|||
Ok(read::read(cache.as_ref(), sri)?)
|
||||
}
|
||||
|
||||
/// Reads the entire contents of a cache file synchronously into a string,
|
||||
/// looking the data up by its content address.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// let sri = cacache::write_sync("./my-cache", "my-key", b"hello")?;
|
||||
/// let data = cacache::read_hash_sync("./my-cache", &sri)?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
pub fn read_hash_to_string_sync<P>(cache: P, sri: &Integrity) -> Result<String>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
Ok(String::from_utf8(read::read(cache.as_ref(), sri)?)?)
|
||||
}
|
||||
|
||||
/// Copies a cache entry by key to a specified location. Returns the number of
|
||||
/// bytes copied.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> cacache::Result<()> {
|
||||
/// cacache::copy_sync("./my-cache", "my-key", "./my-hello.txt")?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
|
|
@ -544,10 +423,9 @@ where
|
|||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write_sync("./my-cache", "my-key", b"hello")?;
|
||||
/// cacache::copy_hash_sync("./my-cache", &sri, "./my-hello.txt")?;
|
||||
/// Ok(())
|
||||
|
|
@ -651,16 +529,6 @@ mod tests {
|
|||
assert_eq!(data, b"hello world");
|
||||
}
|
||||
|
||||
#[async_attributes::test]
|
||||
async fn test_read_to_string() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let dir = tmp.path().to_owned();
|
||||
crate::write(&dir, "my-key", "hello world").await.unwrap();
|
||||
|
||||
let data = crate::read_to_string(&dir, "my-key").await.unwrap();
|
||||
assert_eq!(data, "hello world");
|
||||
}
|
||||
|
||||
#[async_attributes::test]
|
||||
async fn test_read_hash() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
|
|
@ -671,16 +539,6 @@ mod tests {
|
|||
assert_eq!(data, b"hello world");
|
||||
}
|
||||
|
||||
#[async_attributes::test]
|
||||
async fn test_read_hash_to_string() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let dir = tmp.path().to_owned();
|
||||
let sri = crate::write(&dir, "my-key", "hello world").await.unwrap();
|
||||
|
||||
let data = crate::read_hash_to_string(&dir, &sri).await.unwrap();
|
||||
assert_eq!(data, "hello world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_sync() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
|
|
@ -691,16 +549,6 @@ mod tests {
|
|||
assert_eq!(data, b"hello world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_to_string_sync() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let dir = tmp.path().to_owned();
|
||||
crate::write_sync(&dir, "my-key", "hello world").unwrap();
|
||||
|
||||
let data = crate::read_to_string_sync(&dir, "my-key").unwrap();
|
||||
assert_eq!(data, "hello world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_hash_sync() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
|
|
@ -711,16 +559,6 @@ mod tests {
|
|||
assert_eq!(data, b"hello world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_hash_to_string_sync() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let dir = tmp.path().to_owned();
|
||||
let sri = crate::write_sync(&dir, "my-key", "hello world").unwrap();
|
||||
|
||||
let data = crate::read_hash_to_string_sync(&dir, &sri).unwrap();
|
||||
assert_eq!(data, "hello world");
|
||||
}
|
||||
|
||||
#[async_attributes::test]
|
||||
async fn test_copy() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
|
|
|
|||
22
src/index.rs
22
src/index.rs
|
|
@ -5,7 +5,6 @@ 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;
|
||||
use async_std::io::BufReader;
|
||||
use digest::Digest;
|
||||
|
|
@ -20,6 +19,7 @@ use sha2::Sha256;
|
|||
use ssri::Integrity;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
use crate::errors::{Internal, InternalResult, Result};
|
||||
use crate::put::WriteOpts;
|
||||
|
||||
const INDEX_VERSION: &str = "5";
|
||||
|
|
@ -88,7 +88,8 @@ pub fn insert(cache: &Path, key: &str, opts: WriteOpts) -> Result<Integrity> {
|
|||
let out = format!("\n{}\t{}", hash_entry(&stringified), stringified);
|
||||
buck.write_all(out.as_bytes())
|
||||
.with_context(|| format!("Failed to write to index bucket at {:?}", bucket))?;
|
||||
buck.flush()?;
|
||||
buck.flush()
|
||||
.with_context(|| format!("Failed to flush bucket at {:?}", bucket))?;
|
||||
Ok(opts
|
||||
.sri
|
||||
.or_else(|| "sha1-deadbeef".parse::<Integrity>().ok())
|
||||
|
|
@ -125,7 +126,9 @@ pub async fn insert_async<'a>(cache: &'a Path, key: &'a str, opts: WriteOpts) ->
|
|||
buck.write_all(out.as_bytes())
|
||||
.await
|
||||
.with_context(|| format!("Failed to write to index bucket at {:?}", bucket))?;
|
||||
buck.flush().await?;
|
||||
buck.flush()
|
||||
.await
|
||||
.with_context(|| format!("Failed to flush bucket at {:?}", bucket))?;
|
||||
Ok(opts
|
||||
.sri
|
||||
.or_else(|| "sha1-deadbeef".parse::<Integrity>().ok())
|
||||
|
|
@ -223,7 +226,8 @@ pub fn ls(cache: &Path) -> impl Iterator<Item = Result<Metadata>> {
|
|||
WalkDir::new(cache.join(format!("index-v{}", INDEX_VERSION)))
|
||||
.into_iter()
|
||||
.map(|bucket| {
|
||||
let bucket = bucket?;
|
||||
let bucket = bucket.to_internal()?;
|
||||
|
||||
if bucket.file_type().is_dir() {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
|
@ -281,13 +285,13 @@ fn now() -> u128 {
|
|||
.as_millis()
|
||||
}
|
||||
|
||||
fn bucket_entries(bucket: &Path) -> Result<Vec<SerializableMetadata>> {
|
||||
fn bucket_entries(bucket: &Path) -> InternalResult<Vec<SerializableMetadata>> {
|
||||
use std::io::{BufRead, BufReader};
|
||||
fs::File::open(bucket)
|
||||
.map(|file| {
|
||||
BufReader::new(file)
|
||||
.lines()
|
||||
.filter_map(Result::ok)
|
||||
.filter_map(std::result::Result::ok)
|
||||
.filter_map(|entry| {
|
||||
let entry_str = match entry.split('\t').collect::<Vec<&str>>()[..] {
|
||||
[hash, entry_str] if hash_entry(entry_str) == hash => entry_str,
|
||||
|
|
@ -302,19 +306,19 @@ fn bucket_entries(bucket: &Path) -> Result<Vec<SerializableMetadata>> {
|
|||
if err.kind() == ErrorKind::NotFound {
|
||||
Ok(Vec::new())
|
||||
} else {
|
||||
Err(err)?
|
||||
Err(err).to_internal()?
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async fn bucket_entries_async(bucket: &Path) -> Result<Vec<SerializableMetadata>> {
|
||||
async fn bucket_entries_async(bucket: &Path) -> InternalResult<Vec<SerializableMetadata>> {
|
||||
let file_result = afs::File::open(bucket).await;
|
||||
let file;
|
||||
if let Err(err) = file_result {
|
||||
if err.kind() == ErrorKind::NotFound {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
return Err(err.into());
|
||||
return Err(err).to_internal()?;
|
||||
} else {
|
||||
file = file_result.unwrap();
|
||||
}
|
||||
|
|
|
|||
18
src/lib.rs
18
src/lib.rs
|
|
@ -35,10 +35,9 @@
|
|||
//!
|
||||
//! ```no_run
|
||||
//! use async_attributes;
|
||||
//! use anyhow::Result;
|
||||
//!
|
||||
//! #[async_attributes::main]
|
||||
//! async fn main() -> Result<()> {
|
||||
//! async fn main() -> cacache::Result<()> {
|
||||
//! // Data goes in...
|
||||
//! cacache::write("./my-cache", "key", b"hello").await?;
|
||||
//!
|
||||
|
|
@ -60,10 +59,9 @@
|
|||
//!
|
||||
//! ```no_run
|
||||
//! use async_attributes;
|
||||
//! use anyhow::Result;
|
||||
//!
|
||||
//! #[async_attributes::main]
|
||||
//! async fn main() -> Result<()> {
|
||||
//! async fn main() -> cacache::Result<()> {
|
||||
//! // Data goes in...
|
||||
//! let sri = cacache::write("./my-cache", "key", b"hello").await?;
|
||||
//!
|
||||
|
|
@ -81,15 +79,14 @@
|
|||
//! 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<()> {
|
||||
//! async fn main() -> cacache::Result<()> {
|
||||
//! let mut fd = cacache::Writer::create("./my-cache", "key").await?;
|
||||
//! for _ in 0..10 {
|
||||
//! fd.write_all(b"very large data").await?;
|
||||
//! fd.write_all(b"very large data").await.expect("Failed to write to cache");
|
||||
//! }
|
||||
//! // Data is only committed to the cache after you do `fd.commit()`!
|
||||
//! let sri = fd.commit().await?;
|
||||
|
|
@ -97,7 +94,7 @@
|
|||
//!
|
||||
//! let mut fd = cacache::Reader::open("./my-cache", "key").await?;
|
||||
//! let mut buf = String::new();
|
||||
//! fd.read_to_string(&mut buf).await?;
|
||||
//! fd.read_to_string(&mut buf).await.expect("Failed to read to string");
|
||||
//!
|
||||
//! // Make sure to call `.check()` when you're done! It makes sure that what
|
||||
//! // you just read is actually valid. `cacache` always verifies the data
|
||||
|
|
@ -117,8 +114,7 @@
|
|||
//! application, you probably want to use these instead.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use anyhow::Result;
|
||||
//! fn main() -> Result<()> {
|
||||
//! fn main() -> cacache::Result<()> {
|
||||
//! cacache::write_sync("./my-cache", "key", b"my-data").unwrap();
|
||||
//! let data = cacache::read_sync("./my-cache", "key").unwrap();
|
||||
//! assert_eq!(data, b"my-data");
|
||||
|
|
@ -139,7 +135,7 @@ mod ls;
|
|||
mod put;
|
||||
mod rm;
|
||||
|
||||
pub use errors::Error;
|
||||
pub use errors::{Error, Result};
|
||||
pub use index::Metadata;
|
||||
|
||||
pub use get::*;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! Functions for iterating over the cache.
|
||||
use anyhow::Result;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::errors::Result;
|
||||
use crate::index;
|
||||
|
||||
/// Returns a synchronous iterator that lists all cache index entries.
|
||||
|
|
|
|||
94
src/put.rs
94
src/put.rs
|
|
@ -5,12 +5,11 @@ use std::pin::Pin;
|
|||
|
||||
use futures::prelude::*;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use serde_json::Value;
|
||||
use ssri::{Algorithm, Integrity};
|
||||
|
||||
use crate::content::write;
|
||||
use crate::errors::Error;
|
||||
use crate::errors::{Error, Internal, Result};
|
||||
use crate::index;
|
||||
|
||||
use std::task::{Context as TaskContext, Poll};
|
||||
|
|
@ -20,10 +19,9 @@ use std::task::{Context as TaskContext, Poll};
|
|||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// cacache::write("./my-cache", "my-key", b"hello").await?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
|
|
@ -42,13 +40,7 @@ where
|
|||
cache.as_ref()
|
||||
)
|
||||
})?;
|
||||
writer.commit().await.with_context(|| {
|
||||
format!(
|
||||
"Failed to write to commit data for key {} for cache at {:?}",
|
||||
key.as_ref(),
|
||||
cache.as_ref()
|
||||
)
|
||||
})
|
||||
writer.commit().await
|
||||
}
|
||||
|
||||
/// A reference to an open file writing to the cache.
|
||||
|
|
@ -85,12 +77,11 @@ impl Writer {
|
|||
/// ```no_run
|
||||
/// use async_attributes;
|
||||
/// use async_std::prelude::*;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// let mut fd = cacache::Writer::create("./my-cache", "my-key").await?;
|
||||
/// fd.write_all(b"hello world").await?;
|
||||
/// fd.write_all(b"hello world").await.expect("Failed to write to cache");
|
||||
/// // Data is not saved into the cache until you commit it.
|
||||
/// fd.commit().await?;
|
||||
/// Ok(())
|
||||
|
|
@ -105,13 +96,6 @@ impl Writer {
|
|||
.algorithm(Algorithm::Sha256)
|
||||
.open(cache.as_ref(), key.as_ref())
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Failed to open a write handle for key {} for cache at {:?}",
|
||||
key.as_ref(),
|
||||
cache.as_ref()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Closes the Writer handle and writes content and index entries. Also
|
||||
|
|
@ -121,39 +105,20 @@ impl Writer {
|
|||
pub async fn commit(mut self) -> Result<Integrity> {
|
||||
let key = self.key;
|
||||
let cache = self.cache;
|
||||
let writer_sri = self.writer.close().await.with_context(|| {
|
||||
format!(
|
||||
"Failed to properly close save file data for key {} in cache at {:?}",
|
||||
key, cache
|
||||
)
|
||||
})?;
|
||||
let writer_sri = self.writer.close().await?;
|
||||
if let Some(sri) = &self.opts.sri {
|
||||
if sri.matches(&writer_sri).is_none() {
|
||||
return Err(Error::IntegrityError(sri.clone(), writer_sri)).with_context(|| {
|
||||
format!(
|
||||
"Failed to verify data integrity while inserting {} into cache at {:?}",
|
||||
key, cache
|
||||
)
|
||||
})?;
|
||||
return Err(ssri::Error::IntegrityCheckError(sri.clone(), writer_sri))?;
|
||||
}
|
||||
} else {
|
||||
self.opts.sri = Some(writer_sri);
|
||||
}
|
||||
if let Some(size) = self.opts.size {
|
||||
if size != self.written {
|
||||
return Err(Error::SizeError(size, self.written)).with_context(|| {
|
||||
format!("A size was passed in but the value inserted into {} could not be verified for cache at {:?}", key, cache)
|
||||
})?;
|
||||
return Err(Error::SizeError(size, self.written));
|
||||
}
|
||||
}
|
||||
index::insert_async(&cache, &key, self.opts)
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Failed to write index entry for {} in cache at {:?}",
|
||||
key, cache
|
||||
)
|
||||
})
|
||||
index::insert_async(&cache, &key, self.opts).await
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -161,10 +126,9 @@ impl Writer {
|
|||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> cacache::Result<()> {
|
||||
/// let data = cacache::write_sync("./my-cache", "my-key", b"hello")?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
|
|
@ -183,13 +147,7 @@ where
|
|||
cache.as_ref()
|
||||
)
|
||||
})?;
|
||||
writer.commit().with_context(|| {
|
||||
format!(
|
||||
"Failed to write to commit data for key {} for cache at {:?}",
|
||||
key.as_ref(),
|
||||
cache.as_ref()
|
||||
)
|
||||
})
|
||||
writer.commit()
|
||||
}
|
||||
|
||||
/// Builder for options and flags for opening a new cache file to write data into.
|
||||
|
|
@ -304,12 +262,11 @@ impl SyncWriter {
|
|||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::prelude::*;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> cacache::Result<()> {
|
||||
/// let mut fd = cacache::SyncWriter::create("./my-cache", "my-key")?;
|
||||
/// fd.write_all(b"hello world")?;
|
||||
/// fd.write_all(b"hello world").expect("Failed to write to cache");
|
||||
/// // Data is not saved into the cache until you commit it.
|
||||
/// fd.commit()?;
|
||||
/// Ok(())
|
||||
|
|
@ -323,13 +280,6 @@ impl SyncWriter {
|
|||
WriteOpts::new()
|
||||
.algorithm(Algorithm::Sha256)
|
||||
.open_sync(cache.as_ref(), key.as_ref())
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Failed to open a write handle for key {} for cache at {:?}",
|
||||
key.as_ref(),
|
||||
cache.as_ref()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Closes the Writer handle and writes content and index entries. Also
|
||||
|
|
@ -348,29 +298,17 @@ impl SyncWriter {
|
|||
if let Some(sri) = &self.opts.sri {
|
||||
// TODO - ssri should have a .matches method
|
||||
if sri.matches(&writer_sri).is_none() {
|
||||
return Err(Error::IntegrityError(sri.clone(), writer_sri)).with_context(|| {
|
||||
format!(
|
||||
"Failed to verify data integrity while inserting {} into cache at {:?}",
|
||||
key, cache
|
||||
)
|
||||
})?;
|
||||
return Err(ssri::Error::IntegrityCheckError(sri.clone(), writer_sri))?;
|
||||
}
|
||||
} else {
|
||||
self.opts.sri = Some(writer_sri);
|
||||
}
|
||||
if let Some(size) = self.opts.size {
|
||||
if size != self.written {
|
||||
return Err(Error::SizeError(size, self.written)).with_context(|| {
|
||||
format!("A size was passed in but the value inserted into {} could not be verified for cache at {:?}", key, cache)
|
||||
})?;
|
||||
return Err(Error::SizeError(size, self.written))?;
|
||||
}
|
||||
}
|
||||
index::insert(&cache, &key, self.opts).with_context(|| {
|
||||
format!(
|
||||
"Failed to write index entry for {} in cache at {:?}",
|
||||
key, cache
|
||||
)
|
||||
})
|
||||
index::insert(&cache, &key, self.opts)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
62
src/rm.rs
62
src/rm.rs
|
|
@ -4,10 +4,10 @@ use std::path::Path;
|
|||
|
||||
use async_std::fs as afs;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use ssri::Integrity;
|
||||
|
||||
use crate::content::rm;
|
||||
use crate::errors::{Internal, Result};
|
||||
use crate::index;
|
||||
|
||||
/// Removes an individual index metadata entry. The associated content will be
|
||||
|
|
@ -17,10 +17,9 @@ use crate::index;
|
|||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write("./my-cache", "my-key", b"hello").await?;
|
||||
///
|
||||
/// cacache::remove("./my-cache", "my-key").await?;
|
||||
|
|
@ -39,15 +38,7 @@ where
|
|||
P: AsRef<Path>,
|
||||
K: AsRef<str>,
|
||||
{
|
||||
index::delete_async(cache.as_ref(), key.as_ref())
|
||||
.await
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Failed to delete cache entry for {} in cache at {:?}",
|
||||
key.as_ref(),
|
||||
cache.as_ref()
|
||||
)
|
||||
})
|
||||
index::delete_async(cache.as_ref(), key.as_ref()).await
|
||||
}
|
||||
|
||||
/// Removes an individual content entry. Any index entries pointing to this
|
||||
|
|
@ -57,10 +48,9 @@ where
|
|||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write("./my-cache", "my-key", b"hello").await?;
|
||||
///
|
||||
/// cacache::remove_hash("./my-cache", &sri).await?;
|
||||
|
|
@ -76,13 +66,7 @@ where
|
|||
/// }
|
||||
/// ```
|
||||
pub async fn remove_hash<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<()> {
|
||||
rm::rm_async(cache.as_ref(), &sri).await.with_context(|| {
|
||||
format!(
|
||||
"Failed to remove content under {} in cache at {:?}",
|
||||
sri.to_string(),
|
||||
cache.as_ref()
|
||||
)
|
||||
})
|
||||
Ok(rm::rm_async(cache.as_ref(), &sri).await?)
|
||||
}
|
||||
|
||||
/// Removes entire contents of the cache, including temporary files, the entry
|
||||
|
|
@ -92,10 +76,9 @@ pub async fn remove_hash<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<()
|
|||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
/// use anyhow::Result;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> Result<()> {
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write("./my-cache", "my-key", b"hello").await?;
|
||||
///
|
||||
/// cacache::clear("./my-cache").await?;
|
||||
|
|
@ -109,9 +92,9 @@ pub async fn remove_hash<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<()
|
|||
/// }
|
||||
/// ```
|
||||
pub async fn clear<P: AsRef<Path>>(cache: P) -> Result<()> {
|
||||
for entry in cache.as_ref().read_dir()? {
|
||||
for entry in cache.as_ref().read_dir().to_internal()? {
|
||||
if let Ok(entry) = entry {
|
||||
afs::remove_dir_all(entry.path()).await?;
|
||||
afs::remove_dir_all(entry.path()).await.to_internal()?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
@ -122,10 +105,9 @@ pub async fn clear<P: AsRef<Path>>(cache: P) -> Result<()> {
|
|||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write_sync("./my-cache", "my-key", b"hello")?;
|
||||
///
|
||||
/// cacache::remove_sync("./my-cache", "my-key")?;
|
||||
|
|
@ -144,13 +126,7 @@ where
|
|||
P: AsRef<Path>,
|
||||
K: AsRef<str>,
|
||||
{
|
||||
index::delete(cache.as_ref(), key.as_ref()).with_context(|| {
|
||||
format!(
|
||||
"Failed to delete cache entry for {} in cache at {:?}",
|
||||
key.as_ref(),
|
||||
cache.as_ref()
|
||||
)
|
||||
})
|
||||
index::delete(cache.as_ref(), key.as_ref())
|
||||
}
|
||||
|
||||
/// Removes an individual content entry synchronously. Any index entries
|
||||
|
|
@ -158,10 +134,9 @@ where
|
|||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write_sync("./my-cache", "my-key", b"hello")?;
|
||||
///
|
||||
/// cacache::remove_hash_sync("./my-cache", &sri)?;
|
||||
|
|
@ -177,13 +152,7 @@ where
|
|||
/// }
|
||||
/// ```
|
||||
pub fn remove_hash_sync<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<()> {
|
||||
rm::rm(cache.as_ref(), &sri).with_context(|| {
|
||||
format!(
|
||||
"Failed to remove content under {} in cache at {:?}",
|
||||
sri.to_string(),
|
||||
cache.as_ref()
|
||||
)
|
||||
})
|
||||
Ok(rm::rm(cache.as_ref(), &sri)?)
|
||||
}
|
||||
|
||||
/// Removes entire contents of the cache synchronously, including temporary
|
||||
|
|
@ -191,10 +160,9 @@ pub fn remove_hash_sync<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<()>
|
|||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use anyhow::Result;
|
||||
/// use std::io::Read;
|
||||
///
|
||||
/// fn main() -> Result<()> {
|
||||
/// fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write_sync("./my-cache", "my-key", b"hello")?;
|
||||
///
|
||||
/// cacache::clear_sync("./my-cache")?;
|
||||
|
|
@ -208,9 +176,9 @@ pub fn remove_hash_sync<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<()>
|
|||
/// }
|
||||
/// ```
|
||||
pub fn clear_sync<P: AsRef<Path>>(cache: P) -> Result<()> {
|
||||
for entry in cache.as_ref().read_dir()? {
|
||||
for entry in cache.as_ref().read_dir().to_internal()? {
|
||||
if let Ok(entry) = entry {
|
||||
fs::remove_dir_all(entry.path())?;
|
||||
fs::remove_dir_all(entry.path()).to_internal()?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
Loading…
Reference in New Issue