cached_path/lib.rs
1//! The idea behind `cached-path` is to provide a unified, simple interface for
2//! accessing both local and remote files. This can be used behind other APIs that need
3//! to access files agnostic to where they are located.
4//!
5//! This is based on the Python library [`allenai/cached_path`](https://github.com/allenai/cached_path).
6//!
7//! ## Installation
8//!
9//! `cached-path` can be used as both a library and a command-line tool. To install `cached-path`
10//! as a command-line tool, run
11//!
12//! ```bash
13//! cargo install --features build-binary cached-path
14//! ```
15//!
16//! ## Usage
17//!
18//! For remote resources, `cached-path` downloads and caches the resource, using the ETAG
19//! to know when to update the cache. The path returned is the local path to the latest
20//! cached version:
21//!
22//! ```rust
23//! use cached_path::cached_path;
24//!
25//! let path = cached_path(
26//! "https://github.com/epwalsh/rust-cached-path/blob/main/README.md"
27//! ).unwrap();
28//! assert!(path.is_file());
29//! ```
30//!
31//! ```bash
32//! # From the command line:
33//! $ cached-path https://github.com/epwalsh/rust-cached-path/blob/main/README.md
34//! /tmp/cache/055968a99316f3a42e7bcff61d3f590227dd7b03d17e09c41282def7c622ba0f.efa33e7f611ef2d163fea874ce614bb6fa5ab2a9d39d5047425e39ebe59fe782
35//! ```
36//!
37//! For local files, the path returned is just the original path supplied:
38//!
39//! ```rust
40//! use cached_path::cached_path;
41//!
42//! let path = cached_path("README.md").unwrap();
43//! assert_eq!(path.to_str().unwrap(), "README.md");
44//! ```
45//!
46//! ```bash
47//! # From the command line:
48//! $ cached-path README.md
49//! README.md
50//! ```
51//!
52//! For resources that are archives, like `*.tar.gz` files, `cached-path` can also
53//! automatically extract the files:
54//!
55//! ```rust
56//! use cached_path::{cached_path_with_options, Options};
57//!
58//! let path = cached_path_with_options(
59//! "https://raw.githubusercontent.com/epwalsh/rust-cached-path/main/test_fixtures/utf-8_sample/archives/utf-8.tar.gz",
60//! &Options::default().extract(),
61//! ).unwrap();
62//! assert!(path.is_dir());
63//! ```
64//!
65//! ```bash
66//! # From the command line:
67//! $ cached-path --extract https://raw.githubusercontent.com/epwalsh/rust-cached-path/main/test_fixtures/utf-8_sample/archives/utf-8.tar.gz
68//! README.md
69//! ```
70//!
71//! It's also easy to customize the cache location, the HTTP client, and other options
72//! using a [`CacheBuilder`](crate::cache::CacheBuilder) to construct a custom
73//! [`Cache`](crate::cache::Cache) object. This is the recommended thing
74//! to do if your application makes multiple calls to `cached_path`, since it avoids the overhead
75//! of creating a new HTTP client on each call:
76//!
77//! ```rust
78//! use cached_path::Cache;
79//!
80//! let cache = Cache::builder()
81//! .dir(std::env::temp_dir().join("my-cache/"))
82//! .connect_timeout(std::time::Duration::from_secs(3))
83//! .build().unwrap();
84//! let path = cache.cached_path("README.md").unwrap();
85//! ```
86//!
87//! ```bash
88//! # From the command line:
89//! $ cached-path --dir /tmp/my-cache/ --connect-timeout 3 README.md
90//! README.md
91//! ```
92
93use std::path::PathBuf;
94
95pub(crate) mod archives;
96mod cache;
97mod error;
98pub(crate) mod meta;
99mod progress_bar;
100pub(crate) mod utils;
101
102pub use crate::cache::{Cache, CacheBuilder, Options};
103pub use crate::error::Error;
104pub use crate::progress_bar::ProgressBar;
105
106/// Get the cached path to a resource.
107///
108/// This is equivalent to calling [`Cache::cached_path`](crate::cache::Cache#method.cached_path)
109/// with a temporary [`Cache`](crate::cache::Cache) object.
110/// Therefore if you're going to be calling this function multiple times,
111/// it's more efficient to create and use a single `Cache` instead.
112pub fn cached_path(resource: &str) -> Result<PathBuf, Error> {
113 let cache = Cache::builder().build()?;
114 cache.cached_path(resource)
115}
116
117/// Get the cached path to a resource using the given options.
118///
119/// This is equivalent to calling
120/// [`Cache::cached_path_with_options`](crate::cache::Cache#method.cached_path_with_options)
121/// with a temporary [`Cache`](crate::cache::Cache) object.
122/// Therefore if you're going to be calling this function multiple times,
123/// it's more efficient to create and use a single `Cache` instead.
124pub fn cached_path_with_options(resource: &str, options: &Options) -> Result<PathBuf, Error> {
125 let cache = Cache::builder().build()?;
126 cache.cached_path_with_options(resource, options)
127}
128
129#[cfg(test)]
130mod test;