[][src]Crate cacache

cacache is a Rust library for managing local key and content address caches. It's really fast, really good at concurrency, and it will never give you corrupted data, even if cache files get corrupted or manipulated.

Examples

Un-suffixed APIs are all async, using async-std. They let you put data in and get it back out -- asynchronously!

use async_attributes;
use anyhow::Result;

#[async_attributes::main]
async fn main() -> Result<()> {
  // Data goes in...
  cacache::put::data("./my-cache", "key", b"hello").await?;

  // ...data comes out!
  let data = cacache::get::data("./my-cache", "key").await?;
  assert_eq!(data, b"hello");

  Ok(())
}

Lookup by hash

What makes cacache content addressable, though, is its ability to fetch data by its "content address", which in our case is a "subresource integrity" hash, which cacache::put conveniently returns for us. Fetching data by hash is significantly faster than doing key lookups:

use async_attributes;
use anyhow::Result;

#[async_attributes::main]
async fn main() -> Result<()> {
  // Data goes in...
  let sri = cacache::put::data("./my-cache", "key", b"hello").await?;

  // ...data gets looked up by `sri` ("Subresource Integrity").
  let data = cacache::get::data_hash("./my-cache", &sri).await?;
  assert_eq!(data, b"hello");

  Ok(())
}

Large file support

cacache supports large file reads, in both async and sync mode, through an API reminiscent of std::fs::OpenOptions:

use anyhow::Result;
use async_attributes;
use async_std::prelude::*;

#[async_attributes::main]
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?;
  }
  // Data is only persisted to the cache after you do `fd.commit()`!
  let sri = fd.commit().await?;
  println!("integrity: {}", &sri);

  let mut fd = cacache::get::open("./my-cache", "key").await?;
  let mut buf = String::new();
  fd.read_to_string(&mut buf).await?;

  // 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
  // you get out is what it's supposed to be. The check is very cheap!
  fd.check()?;

  Ok(())
}

Sync API

There are also sync APIs available if you don't want to use async/await:

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");
  Ok(())
}

Modules

get

Functions for reading from cache.

ls

Functions for iterating over the cache.

put

Functions for writing to cache.

rm

Functions for removing things from the cache.

Structs

Entry

Represents a cache index entry, which points to content.

Enums

Algorithm

Valid algorithms for integrity strings.

Error

Error type returned by all API calls.

Value

Represents any valid JSON value.