mirror of https://github.com/zkat/cacache-rs.git
Merge 6310b21632 into 66eae4b78f
This commit is contained in:
commit
4e3ba3dbab
|
|
@ -118,16 +118,30 @@ pub fn read(cache: &Path, sri: &Integrity) -> Result<Vec<u8>> {
|
|||
}
|
||||
|
||||
#[cfg(any(feature = "async-std", feature = "tokio"))]
|
||||
pub async fn read_async<'a>(cache: &'a Path, sri: &'a Integrity) -> Result<Vec<u8>> {
|
||||
let cpath = path::content_path(cache, sri);
|
||||
pub async fn read_async<'c, 's>(cache: &'c Path, sri: Integrity, verify_integrity: bool) -> Result<(Vec<u8>, Integrity)> {
|
||||
let cpath = path::content_path(&cache, &sri);
|
||||
let ret = crate::async_lib::read(&cpath).await.with_context(|| {
|
||||
format!(
|
||||
"Failed to read contents for file at {}",
|
||||
path::content_path(cache, sri).display()
|
||||
path::content_path(&cache, &sri).display()
|
||||
)
|
||||
})?;
|
||||
Ok(if verify_integrity {
|
||||
// we require owned Integrity because of the below move which would otherwise try to
|
||||
// provide a reference to a closure that moves to another thread, i.e. `'s: 'static` which fails
|
||||
let integrity_check = move || {
|
||||
sri.check(&ret)?;
|
||||
Ok(ret)
|
||||
Ok::<_, ssri::Error>((sri, ret))
|
||||
};
|
||||
#[cfg(feature = "tokio")]
|
||||
let (sri, ret) = tokio::task::spawn_blocking(integrity_check).await??;
|
||||
#[cfg(feature = "async-std")]
|
||||
let (sri, ret) = async_std::task::spawn_blocking(integrity_check).await?;
|
||||
|
||||
(ret, sri)
|
||||
} else {
|
||||
(ret, sri)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn reflink_unchecked(cache: &Path, sri: &Integrity, to: &Path) -> Result<()> {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,12 @@ pub enum Error {
|
|||
#[error(transparent)]
|
||||
#[diagnostic(code(cacache::integrity_error), url(docsrs))]
|
||||
IntegrityError(#[from] ssri::Error),
|
||||
|
||||
/// Returned when a Tokio join error occured.
|
||||
#[cfg(feature="tokio")]
|
||||
#[error(transparent)]
|
||||
#[diagnostic(code(cacache::tokio_joinerror), url(docsrs))]
|
||||
TokioJoinError(#[from] tokio::task::JoinError)
|
||||
}
|
||||
|
||||
/// The result type returned by calls to this library
|
||||
|
|
|
|||
69
src/get.rs
69
src/get.rs
|
|
@ -159,7 +159,40 @@ where
|
|||
{
|
||||
async fn inner(cache: &Path, key: &str) -> Result<Vec<u8>> {
|
||||
if let Some(entry) = index::find_async(cache, key).await? {
|
||||
read_hash(cache, &entry.integrity).await
|
||||
read_hash(cache, entry.integrity).await.map(|(r, _i)| r)
|
||||
} else {
|
||||
Err(Error::EntryNotFound(cache.to_path_buf(), key.into()))
|
||||
}
|
||||
}
|
||||
inner(cache.as_ref(), key.as_ref()).await
|
||||
}
|
||||
|
||||
/// Reads the entire contents of a cache file into a bytes vector, looking the
|
||||
/// data up by key. Skips integrity checking. Use this for loading large files.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// let data: Vec<u8> = cacache::read_no_integrity("./my-cache", "my-key").await?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// If you have no integrity this function is for you.
|
||||
#[doc(hidden)]
|
||||
#[cfg(any(feature = "async-std", feature = "tokio"))]
|
||||
pub async fn read_no_integrity<P, K>(cache: P, key: K) -> Result<Vec<u8>>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
K: AsRef<str>,
|
||||
{
|
||||
async fn inner(cache: &Path, key: &str) -> Result<Vec<u8>> {
|
||||
if let Some(entry) = index::find_async(cache, key).await? {
|
||||
read_hash_no_integrity(cache, entry.integrity).await.map(|(r, _i)| r)
|
||||
} else {
|
||||
Err(Error::EntryNotFound(cache.to_path_buf(), key.into()))
|
||||
}
|
||||
|
|
@ -178,16 +211,42 @@ where
|
|||
/// #[async_attributes::main]
|
||||
/// 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?;
|
||||
/// let (data, _): (Vec<u8>, _) = cacache::read_hash("./my-cache", sri).await?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(any(feature = "async-std", feature = "tokio"))]
|
||||
pub async fn read_hash<P>(cache: P, sri: &Integrity) -> Result<Vec<u8>>
|
||||
pub async fn read_hash<P>(cache: P, sri: Integrity) -> Result<(Vec<u8>, Integrity)>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
read::read_async(cache.as_ref(), sri).await
|
||||
read::read_async(cache.as_ref(), sri, true).await
|
||||
}
|
||||
|
||||
/// Reads the entire contents of a cache file into a bytes vector, looking the
|
||||
/// data up by its content address. Skips integrity checking. Use this for large files.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```no_run
|
||||
/// use async_std::prelude::*;
|
||||
/// use async_attributes;
|
||||
///
|
||||
/// #[async_attributes::main]
|
||||
/// async fn main() -> cacache::Result<()> {
|
||||
/// let sri = cacache::write("./my-cache", "my-key", b"hello").await?;
|
||||
/// let (data, _): (Vec<u8>, _) = cacache::read_hash_no_integrity("./my-cache", sri).await?;
|
||||
/// Ok(())
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// If you have no integrity this function is for you.
|
||||
#[doc(hidden)]
|
||||
#[cfg(any(feature = "async-std", feature = "tokio"))]
|
||||
pub async fn read_hash_no_integrity<P>(cache: P, sri: Integrity) -> Result<(Vec<u8>, Integrity)>
|
||||
where
|
||||
P: AsRef<Path>,
|
||||
{
|
||||
read::read_async(cache.as_ref(), sri, false).await
|
||||
}
|
||||
|
||||
/// Copies cache data to a specified location. Returns the number of bytes
|
||||
|
|
@ -995,7 +1054,7 @@ mod tests {
|
|||
let dir = tmp.path().to_owned();
|
||||
let sri = crate::write(&dir, "my-key", b"hello world").await.unwrap();
|
||||
|
||||
let data = crate::read_hash(&dir, &sri).await.unwrap();
|
||||
let (data, _) = crate::read_hash(&dir, sri).await.unwrap();
|
||||
assert_eq!(data, b"hello world");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
//! let sri = cacache::write("./my-cache", "key", b"hello").await?;
|
||||
//!
|
||||
//! // ...data gets looked up by `sri` ("Subresource Integrity").
|
||||
//! let data = cacache::read_hash("./my-cache", &sri).await?;
|
||||
//! let (data, _) = cacache::read_hash("./my-cache", sri).await?;
|
||||
//! assert_eq!(data, b"hello");
|
||||
//!
|
||||
//! Ok(())
|
||||
|
|
|
|||
|
|
@ -652,7 +652,7 @@ mod tests {
|
|||
let integrity = crate::write_hash(&dir, &original)
|
||||
.await
|
||||
.expect("should be able to write a hash asynchronously");
|
||||
let bytes = crate::read_hash(&dir, &integrity)
|
||||
let (bytes, _) = crate::read_hash(&dir, integrity)
|
||||
.await
|
||||
.expect("should be able to read back what we wrote");
|
||||
let result =
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ use crate::index;
|
|||
/// cacache::read("./my-cache", "my-key").await?;
|
||||
///
|
||||
/// // But this succeeds:
|
||||
/// cacache::read_hash("./my-cache", &sri).await?;
|
||||
/// cacache::read_hash("./my-cache", sri).await?;
|
||||
///
|
||||
/// Ok(())
|
||||
/// }
|
||||
|
|
@ -56,7 +56,7 @@ where
|
|||
///
|
||||
/// // These fail:
|
||||
/// cacache::read("./my-cache", "my-key").await?;
|
||||
/// cacache::read_hash("./my-cache", &sri).await?;
|
||||
/// cacache::read_hash("./my-cache", sri).await?;
|
||||
///
|
||||
/// // But this succeeds:
|
||||
/// cacache::metadata("./my-cache", "my-key").await?;
|
||||
|
|
@ -86,7 +86,7 @@ pub async fn remove_hash<P: AsRef<Path>>(cache: P, sri: &Integrity) -> Result<()
|
|||
/// // These all fail:
|
||||
/// cacache::read("./my-cache", "my-key").await?;
|
||||
/// cacache::metadata("./my-cache", "my-key").await?;
|
||||
/// cacache::read_hash("./my-cache", &sri).await?;
|
||||
/// cacache::read_hash("./my-cache", sri).await?;
|
||||
///
|
||||
/// Ok(())
|
||||
/// }
|
||||
|
|
|
|||
Loading…
Reference in New Issue