mirror of https://github.com/zkat/cacache-rs.git
feat(link_to): rename feature link to link_to
This commit is contained in:
parent
7fb373ce5b
commit
292e5d0cdc
|
|
@ -53,5 +53,5 @@ harness = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["async-std", "async-attributes"]
|
default = ["async-std", "async-attributes"]
|
||||||
link = []
|
link_to = []
|
||||||
tokio-runtime = ["tokio", "tokio-stream"]
|
tokio-runtime = ["tokio", "tokio-stream"]
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ Minimum supported Rust version is `1.43.0`.
|
||||||
cacache = { version = "*", default-features = false, features = ["tokio-runtime"] }
|
cacache = { version = "*", default-features = false, features = ["tokio-runtime"] }
|
||||||
```
|
```
|
||||||
|
|
||||||
Experimental support for tracking existing files through symlinks is provided
|
Experimental support for symlinking to existing files is provided via the
|
||||||
via the "link" feature.
|
"link_to" feature.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,7 @@ fn write_hash_async(c: &mut Criterion) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "link_to")]
|
||||||
fn create_tmpfile(tmp: &tempfile::TempDir, buf: &[u8]) -> PathBuf {
|
fn create_tmpfile(tmp: &tempfile::TempDir, buf: &[u8]) -> PathBuf {
|
||||||
let dir = tmp.path().to_owned();
|
let dir = tmp.path().to_owned();
|
||||||
let target = dir.join("target-file");
|
let target = dir.join("target-file");
|
||||||
|
|
@ -218,8 +219,8 @@ fn create_tmpfile(tmp: &tempfile::TempDir, buf: &[u8]) -> PathBuf {
|
||||||
target
|
target
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "link")]
|
#[cfg(feature = "link_to")]
|
||||||
fn link_async(c: &mut Criterion) {
|
fn link_to_async(c: &mut Criterion) {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let target = create_tmpfile(&tmp, b"hello world");
|
let target = create_tmpfile(&tmp, b"hello world");
|
||||||
|
|
||||||
|
|
@ -229,27 +230,32 @@ fn link_async(c: &mut Criterion) {
|
||||||
b.iter_custom(|iters| {
|
b.iter_custom(|iters| {
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
for i in 0..iters {
|
for i in 0..iters {
|
||||||
block_on(cacache::link(&cache, format!("key{}", i), target.clone())).unwrap();
|
block_on(cacache::link_to(
|
||||||
|
&cache,
|
||||||
|
format!("key{}", i),
|
||||||
|
target.clone(),
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
start.elapsed()
|
start.elapsed()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "link")]
|
#[cfg(feature = "link_to")]
|
||||||
fn link_hash_async(c: &mut Criterion) {
|
fn link_to_hash_async(c: &mut Criterion) {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let target = create_tmpfile(&tmp, b"hello world");
|
let target = create_tmpfile(&tmp, b"hello world");
|
||||||
|
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let cache = tmp.path().to_owned();
|
let cache = tmp.path().to_owned();
|
||||||
c.bench_function("link::file_hash", move |b| {
|
c.bench_function("link::file_hash", move |b| {
|
||||||
b.iter(|| block_on(cacache::link_hash(&cache, target.clone())).unwrap())
|
b.iter(|| block_on(cacache::link_to_hash(&cache, target.clone())).unwrap())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "link")]
|
#[cfg(feature = "link_to")]
|
||||||
fn link_sync(c: &mut Criterion) {
|
fn link_to_sync(c: &mut Criterion) {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let target = create_tmpfile(&tmp, b"hello world");
|
let target = create_tmpfile(&tmp, b"hello world");
|
||||||
|
|
||||||
|
|
@ -259,22 +265,22 @@ fn link_sync(c: &mut Criterion) {
|
||||||
b.iter_custom(|iters| {
|
b.iter_custom(|iters| {
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
for i in 0..iters {
|
for i in 0..iters {
|
||||||
cacache::link_sync(&cache, format!("key{}", i), target.clone()).unwrap();
|
cacache::link_to_sync(&cache, format!("key{}", i), target.clone()).unwrap();
|
||||||
}
|
}
|
||||||
start.elapsed()
|
start.elapsed()
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "link")]
|
#[cfg(feature = "link_to")]
|
||||||
fn link_hash_sync(c: &mut Criterion) {
|
fn link_to_hash_sync(c: &mut Criterion) {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let target = create_tmpfile(&tmp, b"hello world");
|
let target = create_tmpfile(&tmp, b"hello world");
|
||||||
|
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let cache = tmp.path().to_owned();
|
let cache = tmp.path().to_owned();
|
||||||
c.bench_function("link::file_hash_sync", move |b| {
|
c.bench_function("link::file_hash_sync", move |b| {
|
||||||
b.iter(|| cacache::link_hash_sync(&cache, target.clone()).unwrap())
|
b.iter(|| cacache::link_to_hash_sync(&cache, target.clone()).unwrap())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -295,16 +301,16 @@ criterion_group!(
|
||||||
read_hash_sync_big_data
|
read_hash_sync_big_data
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "link")]
|
#[cfg(feature = "link_to")]
|
||||||
criterion_group!(
|
criterion_group!(
|
||||||
link_benches,
|
link_to_benches,
|
||||||
link_async,
|
link_to_async,
|
||||||
link_hash_async,
|
link_to_hash_async,
|
||||||
link_sync,
|
link_to_sync,
|
||||||
link_hash_sync
|
link_to_hash_sync
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "link")]
|
#[cfg(feature = "link_to")]
|
||||||
criterion_main!(benches, link_benches);
|
criterion_main!(benches, link_to_benches);
|
||||||
#[cfg(not(feature = "link"))]
|
#[cfg(not(feature = "link_to"))]
|
||||||
criterion_main!(benches);
|
criterion_main!(benches);
|
||||||
|
|
|
||||||
|
|
@ -59,9 +59,9 @@ fn create_symlink(sri: Integrity, cache: &PathBuf, target: &PathBuf) -> Result<I
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `Read`-like type that calculates the integrity of a file as it is read.
|
/// A `Read`-like type that calculates the integrity of a file as it is read.
|
||||||
/// When the linker is committed, the file is symlinked into the cache using the
|
/// When the linker is committed, a symlink is created from the cache to the
|
||||||
/// integrity computed from the target file's contents.
|
/// target file using the integrity computed from the file's contents.
|
||||||
pub struct Linker {
|
pub struct ToLinker {
|
||||||
/// The path to the target file that will be symlinked from the cache.
|
/// The path to the target file that will be symlinked from the cache.
|
||||||
target: PathBuf,
|
target: PathBuf,
|
||||||
/// The path to the root of the cache directory.
|
/// The path to the root of the cache directory.
|
||||||
|
|
@ -72,7 +72,7 @@ pub struct Linker {
|
||||||
builder: IntegrityOpts,
|
builder: IntegrityOpts,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Linker {
|
impl ToLinker {
|
||||||
pub fn new(cache: &Path, algo: Algorithm, target: &Path) -> Result<Self> {
|
pub fn new(cache: &Path, algo: Algorithm, target: &Path) -> Result<Self> {
|
||||||
let file = File::open(target)
|
let file = File::open(target)
|
||||||
.with_context(|| format!("Failed to open reader to {}", target.display()))?;
|
.with_context(|| format!("Failed to open reader to {}", target.display()))?;
|
||||||
|
|
@ -84,13 +84,13 @@ impl Linker {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consume the Linker and commit the symlink to the cache.
|
/// Add the symlink to the target file from the cache.
|
||||||
pub fn commit(self) -> Result<Integrity> {
|
pub fn commit(self) -> Result<Integrity> {
|
||||||
create_symlink(self.builder.result(), &self.cache, &self.target)
|
create_symlink(self.builder.result(), &self.cache, &self.target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::io::Read for Linker {
|
impl std::io::Read for ToLinker {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
let amt = self.fd.read(buf)?;
|
let amt = self.fd.read(buf)?;
|
||||||
if amt > 0 {
|
if amt > 0 {
|
||||||
|
|
@ -101,9 +101,9 @@ impl std::io::Read for Linker {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An `AsyncRead`-like type that calculates the integrity of a file as it is
|
/// An `AsyncRead`-like type that calculates the integrity of a file as it is
|
||||||
/// read. When the linker is committed, the file is symlinked into the cache
|
/// read. When the linker is committed, a symlink is created from the cache to
|
||||||
/// using the integrity computed from the target file's contents.
|
/// the target file using the integrity computed from the file's contents.
|
||||||
pub struct AsyncLinker {
|
pub struct AsyncToLinker {
|
||||||
/// The path to the target file that will be symlinked from the cache.
|
/// The path to the target file that will be symlinked from the cache.
|
||||||
target: PathBuf,
|
target: PathBuf,
|
||||||
/// The path to the root of the cache directory.
|
/// The path to the root of the cache directory.
|
||||||
|
|
@ -114,7 +114,7 @@ pub struct AsyncLinker {
|
||||||
builder: IntegrityOpts,
|
builder: IntegrityOpts,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncRead for AsyncLinker {
|
impl AsyncRead for AsyncToLinker {
|
||||||
#[cfg(feature = "async-std")]
|
#[cfg(feature = "async-std")]
|
||||||
fn poll_read(
|
fn poll_read(
|
||||||
mut self: Pin<&mut Self>,
|
mut self: Pin<&mut Self>,
|
||||||
|
|
@ -143,7 +143,7 @@ impl AsyncRead for AsyncLinker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncLinker {
|
impl AsyncToLinker {
|
||||||
pub async fn new(cache: &Path, algo: Algorithm, target: &Path) -> Result<Self> {
|
pub async fn new(cache: &Path, algo: Algorithm, target: &Path) -> Result<Self> {
|
||||||
let file = crate::async_lib::File::open(target)
|
let file = crate::async_lib::File::open(target)
|
||||||
.await
|
.await
|
||||||
|
|
@ -156,7 +156,7 @@ impl AsyncLinker {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consume the Linker and commit the symlink to the cache.
|
/// Add the symlink to the target file from the cache.
|
||||||
pub async fn commit(self) -> Result<Integrity> {
|
pub async fn commit(self) -> Result<Integrity> {
|
||||||
create_symlink(self.builder.result(), &self.cache, &self.target)
|
create_symlink(self.builder.result(), &self.cache, &self.target)
|
||||||
}
|
}
|
||||||
|
|
@ -195,7 +195,7 @@ mod tests {
|
||||||
|
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let dir = tmp.path().to_owned();
|
let dir = tmp.path().to_owned();
|
||||||
let mut linker = Linker::new(&dir, Algorithm::Sha256, &target).unwrap();
|
let mut linker = ToLinker::new(&dir, Algorithm::Sha256, &target).unwrap();
|
||||||
|
|
||||||
// read all of the data from the linker, which will calculate the integrity
|
// read all of the data from the linker, which will calculate the integrity
|
||||||
// hash.
|
// hash.
|
||||||
|
|
@ -223,7 +223,7 @@ mod tests {
|
||||||
|
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let dir = tmp.path().to_owned();
|
let dir = tmp.path().to_owned();
|
||||||
let mut linker = AsyncLinker::new(&dir, Algorithm::Sha256, &target)
|
let mut linker = AsyncToLinker::new(&dir, Algorithm::Sha256, &target)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
@ -3,5 +3,5 @@ pub mod read;
|
||||||
pub mod rm;
|
pub mod rm;
|
||||||
pub mod write;
|
pub mod write;
|
||||||
|
|
||||||
#[cfg(feature = "link")]
|
#[cfg(feature = "link_to")]
|
||||||
pub mod symlink;
|
pub mod linkto;
|
||||||
|
|
|
||||||
24
src/lib.rs
24
src/lib.rs
|
|
@ -122,21 +122,21 @@
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ### Linking exsiting files
|
//! ### Linking to existing files
|
||||||
//!
|
//!
|
||||||
//! The `link` feature enables an additional set of APIs for adding existing
|
//! The `link_to` feature enables an additional set of APIs for adding existing
|
||||||
//! files into the cache via symlinks, without having to duplicate the data.
|
//! files into the cache via symlinks, without having to duplicate their data.
|
||||||
//! Once linked into the cache, these files can be accessed by key just like
|
//! Once the cache links to them, these files can be accessed by key just like
|
||||||
//! other cached data, with the same integrity checking.
|
//! other cached data, with the same integrity checking.
|
||||||
//!
|
//!
|
||||||
//! The `link` methods are available in both async and sync variants, using the
|
//! The `link_to` methods are available in both async and sync variants, using
|
||||||
//! same suffixes as the other APIs.
|
//! the same suffixes as the other APIs.
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! #[async_attributes::main]
|
//! #[async_attributes::main]
|
||||||
//! async fn main() -> cacache::Result<()> {
|
//! async fn main() -> cacache::Result<()> {
|
||||||
//! #[cfg(feature = "link")]
|
//! #[cfg(feature = "link_to")]
|
||||||
//! cacache::link("./my-cache", "key", "/path/to/my-other-file.txt").await?;
|
//! cacache::link_to("./my-cache", "key", "/path/to/my-other-file.txt").await?;
|
||||||
//! let data = cacache::read("./my-cache", "key").await?;
|
//! let data = cacache::read("./my-cache", "key").await?;
|
||||||
//! assert_eq!(data, b"my-data");
|
//! assert_eq!(data, b"my-data");
|
||||||
//! Ok(())
|
//! Ok(())
|
||||||
|
|
@ -160,8 +160,8 @@ mod errors;
|
||||||
pub mod index;
|
pub mod index;
|
||||||
|
|
||||||
mod get;
|
mod get;
|
||||||
#[cfg(feature = "link")]
|
#[cfg(feature = "link_to")]
|
||||||
mod link;
|
mod linkto;
|
||||||
mod ls;
|
mod ls;
|
||||||
mod put;
|
mod put;
|
||||||
mod rm;
|
mod rm;
|
||||||
|
|
@ -170,8 +170,8 @@ pub use errors::{Error, Result};
|
||||||
pub use index::Metadata;
|
pub use index::Metadata;
|
||||||
|
|
||||||
pub use get::*;
|
pub use get::*;
|
||||||
#[cfg(feature = "link")]
|
#[cfg(feature = "link_to")]
|
||||||
pub use link::*;
|
pub use linkto::*;
|
||||||
pub use ls::*;
|
pub use ls::*;
|
||||||
pub use put::*;
|
pub use put::*;
|
||||||
pub use rm::*;
|
pub use rm::*;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::async_lib::AsyncRead;
|
use crate::async_lib::AsyncRead;
|
||||||
use crate::content::symlink;
|
use crate::content::linkto;
|
||||||
use crate::errors::{Error, IoErrorExt, Result};
|
use crate::errors::{Error, IoErrorExt, Result};
|
||||||
use crate::{index, WriteOpts};
|
use crate::{index, WriteOpts};
|
||||||
use ssri::{Algorithm, Integrity};
|
use ssri::{Algorithm, Integrity};
|
||||||
|
|
@ -26,17 +26,17 @@ const PROBE_SIZE: usize = 8;
|
||||||
///
|
///
|
||||||
/// #[async_attributes::main]
|
/// #[async_attributes::main]
|
||||||
/// async fn main() -> cacache::Result<()> {
|
/// async fn main() -> cacache::Result<()> {
|
||||||
/// cacache::link("./my-cache", "my-key", "../my-other-files/my-file.tgz").await?;
|
/// cacache::link_to("./my-cache", "my-key", "../my-other-files/my-file.tgz").await?;
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn link<P, K, T>(cache: P, key: K, target: T) -> Result<Integrity>
|
pub async fn link_to<P, K, T>(cache: P, key: K, target: T) -> Result<Integrity>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
K: AsRef<str>,
|
K: AsRef<str>,
|
||||||
T: AsRef<Path>,
|
T: AsRef<Path>,
|
||||||
{
|
{
|
||||||
Linker::open(cache, key, target).await?.commit().await
|
ToLinker::open(cache, key, target).await?.commit().await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Asynchrounously adds `target` to the `cache` with a symlink, skipping
|
/// Asynchrounously adds `target` to the `cache` with a symlink, skipping
|
||||||
|
|
@ -49,20 +49,20 @@ where
|
||||||
///
|
///
|
||||||
/// #[async_attributes::main]
|
/// #[async_attributes::main]
|
||||||
/// async fn main() -> cacache::Result<()> {
|
/// async fn main() -> cacache::Result<()> {
|
||||||
/// cacache::link_hash("./my-cache", "../my-other-files/my-file.tgz").await?;
|
/// cacache::link_to_hash("./my-cache", "../my-other-files/my-file.tgz").await?;
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub async fn link_hash<P, T>(cache: P, target: T) -> Result<Integrity>
|
pub async fn link_to_hash<P, T>(cache: P, target: T) -> Result<Integrity>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
T: AsRef<Path>,
|
T: AsRef<Path>,
|
||||||
{
|
{
|
||||||
Linker::open_hash(cache, target).await?.commit().await
|
ToLinker::open_hash(cache, target).await?.commit().await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Synchronously adds `target` to the `cache` with a symlink, indexing it under
|
/// Synchronously creates a symlink in the `cache` to the `target`, indexing it
|
||||||
/// `key`.
|
/// under `key`.
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
|
|
@ -70,20 +70,20 @@ where
|
||||||
/// use std::path::Path;
|
/// use std::path::Path;
|
||||||
///
|
///
|
||||||
/// fn main() -> cacache::Result<()> {
|
/// fn main() -> cacache::Result<()> {
|
||||||
/// cacache::link_sync("./my-cache", "my-key", "../my-other-files/my-file.tgz")?;
|
/// cacache::link_to_sync("./my-cache", "my-key", "../my-other-files/my-file.tgz")?;
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn link_sync<P, K, T>(cache: P, key: K, target: T) -> Result<Integrity>
|
pub fn link_to_sync<P, K, T>(cache: P, key: K, target: T) -> Result<Integrity>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
K: AsRef<str>,
|
K: AsRef<str>,
|
||||||
T: AsRef<Path>,
|
T: AsRef<Path>,
|
||||||
{
|
{
|
||||||
SyncLinker::open(cache, key, target)?.commit()
|
SyncToLinker::open(cache, key, target)?.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Synchronously adds `target` to the `cache` with a symlink, skipping
|
/// Synchronously creates a symlink in the `cache` to the `target`, skipping
|
||||||
/// associating an index key with it.
|
/// associating an index key with it.
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Example
|
||||||
|
|
@ -92,34 +92,39 @@ where
|
||||||
/// use std::path::Path;
|
/// use std::path::Path;
|
||||||
///
|
///
|
||||||
/// fn main() -> cacache::Result<()> {
|
/// fn main() -> cacache::Result<()> {
|
||||||
/// cacache::link_hash_sync("./my-cache", "../foo/bar.tgz")?;
|
/// cacache::link_to_hash_sync("./my-cache", "../foo/bar.tgz")?;
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn link_hash_sync<P, T>(cache: P, target: T) -> Result<Integrity>
|
pub fn link_to_hash_sync<P, T>(cache: P, target: T) -> Result<Integrity>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
T: AsRef<Path>,
|
T: AsRef<Path>,
|
||||||
{
|
{
|
||||||
SyncLinker::open_hash(cache, target)?.commit()
|
SyncToLinker::open_hash(cache, target)?.commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extend the `WriteOpts` struct with factories for creating `Linker` and
|
/// Extend the `WriteOpts` struct with factories for creating `ToLinker` and
|
||||||
/// `SyncLinker` instances.
|
/// `SyncToLinker` instances.
|
||||||
impl WriteOpts {
|
impl WriteOpts {
|
||||||
/// Opens the target file handle for reading, returning a Linker instance.
|
/// Opens the target file handle for reading, returning a ToLinker instance.
|
||||||
pub async fn link<P, K, T>(self, cache: P, key: K, target: T) -> Result<Linker>
|
pub async fn link_to<P, K, T>(self, cache: P, key: K, target: T) -> Result<ToLinker>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
K: AsRef<str>,
|
K: AsRef<str>,
|
||||||
T: AsRef<Path>,
|
T: AsRef<Path>,
|
||||||
{
|
{
|
||||||
async fn inner(opts: WriteOpts, cache: &Path, key: &str, target: &Path) -> Result<Linker> {
|
async fn inner(
|
||||||
Ok(Linker {
|
opts: WriteOpts,
|
||||||
|
cache: &Path,
|
||||||
|
key: &str,
|
||||||
|
target: &Path,
|
||||||
|
) -> Result<ToLinker> {
|
||||||
|
Ok(ToLinker {
|
||||||
cache: cache.to_path_buf(),
|
cache: cache.to_path_buf(),
|
||||||
key: Some(String::from(key)),
|
key: Some(String::from(key)),
|
||||||
read: 0,
|
read: 0,
|
||||||
linker: symlink::AsyncLinker::new(
|
linker: linkto::AsyncToLinker::new(
|
||||||
cache,
|
cache,
|
||||||
opts.algorithm.unwrap_or(Algorithm::Sha256),
|
opts.algorithm.unwrap_or(Algorithm::Sha256),
|
||||||
target,
|
target,
|
||||||
|
|
@ -132,18 +137,18 @@ impl WriteOpts {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opens the target file handle for reading, without a key, returning a
|
/// Opens the target file handle for reading, without a key, returning a
|
||||||
/// Linker instance.
|
/// ToLinker instance.
|
||||||
pub async fn link_hash<P, T>(self, cache: P, target: T) -> Result<Linker>
|
pub async fn link_to_hash<P, T>(self, cache: P, target: T) -> Result<ToLinker>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
T: AsRef<Path>,
|
T: AsRef<Path>,
|
||||||
{
|
{
|
||||||
async fn inner(opts: WriteOpts, cache: &Path, target: &Path) -> Result<Linker> {
|
async fn inner(opts: WriteOpts, cache: &Path, target: &Path) -> Result<ToLinker> {
|
||||||
Ok(Linker {
|
Ok(ToLinker {
|
||||||
cache: cache.to_path_buf(),
|
cache: cache.to_path_buf(),
|
||||||
key: None,
|
key: None,
|
||||||
read: 0,
|
read: 0,
|
||||||
linker: symlink::AsyncLinker::new(
|
linker: linkto::AsyncToLinker::new(
|
||||||
cache,
|
cache,
|
||||||
opts.algorithm.unwrap_or(Algorithm::Sha256),
|
opts.algorithm.unwrap_or(Algorithm::Sha256),
|
||||||
target,
|
target,
|
||||||
|
|
@ -156,19 +161,19 @@ impl WriteOpts {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opens the target file handle for reading synchronously, returning a
|
/// Opens the target file handle for reading synchronously, returning a
|
||||||
/// SyncLinker instance.
|
/// SyncToLinker instance.
|
||||||
pub fn link_sync<P, K, T>(self, cache: P, key: K, target: T) -> Result<SyncLinker>
|
pub fn link_to_sync<P, K, T>(self, cache: P, key: K, target: T) -> Result<SyncToLinker>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
K: AsRef<str>,
|
K: AsRef<str>,
|
||||||
T: AsRef<Path>,
|
T: AsRef<Path>,
|
||||||
{
|
{
|
||||||
fn inner(opts: WriteOpts, cache: &Path, key: &str, target: &Path) -> Result<SyncLinker> {
|
fn inner(opts: WriteOpts, cache: &Path, key: &str, target: &Path) -> Result<SyncToLinker> {
|
||||||
Ok(SyncLinker {
|
Ok(SyncToLinker {
|
||||||
cache: cache.to_path_buf(),
|
cache: cache.to_path_buf(),
|
||||||
key: Some(String::from(key)),
|
key: Some(String::from(key)),
|
||||||
read: 0,
|
read: 0,
|
||||||
linker: symlink::Linker::new(
|
linker: linkto::ToLinker::new(
|
||||||
cache,
|
cache,
|
||||||
opts.algorithm.unwrap_or(Algorithm::Sha256),
|
opts.algorithm.unwrap_or(Algorithm::Sha256),
|
||||||
target,
|
target,
|
||||||
|
|
@ -180,18 +185,18 @@ impl WriteOpts {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opens the target file handle for reading synchronously, without a key,
|
/// Opens the target file handle for reading synchronously, without a key,
|
||||||
/// returning a SyncLinker instance.
|
/// returning a SyncToLinker instance.
|
||||||
pub fn link_hash_sync<P, T>(self, cache: P, target: T) -> Result<SyncLinker>
|
pub fn link_to_hash_sync<P, T>(self, cache: P, target: T) -> Result<SyncToLinker>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
T: AsRef<Path>,
|
T: AsRef<Path>,
|
||||||
{
|
{
|
||||||
fn inner(opts: WriteOpts, cache: &Path, target: &Path) -> Result<SyncLinker> {
|
fn inner(opts: WriteOpts, cache: &Path, target: &Path) -> Result<SyncToLinker> {
|
||||||
Ok(SyncLinker {
|
Ok(SyncToLinker {
|
||||||
cache: cache.to_path_buf(),
|
cache: cache.to_path_buf(),
|
||||||
key: None,
|
key: None,
|
||||||
read: 0,
|
read: 0,
|
||||||
linker: symlink::Linker::new(
|
linker: linkto::ToLinker::new(
|
||||||
cache,
|
cache,
|
||||||
opts.algorithm.unwrap_or(Algorithm::Sha256),
|
opts.algorithm.unwrap_or(Algorithm::Sha256),
|
||||||
target,
|
target,
|
||||||
|
|
@ -203,20 +208,20 @@ impl WriteOpts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A file handle for asynchronously reading data from a file to be added to the
|
/// A file handle for asynchronously reading in data from a file to be added to
|
||||||
/// cache via a symlink.
|
/// the cache via a symlink to the target file.
|
||||||
///
|
///
|
||||||
/// Make sure to call `.commit()` when done reading to actually add the file to
|
/// Make sure to call `.commit()` when done reading to actually add the file to
|
||||||
/// the cache.
|
/// the cache.
|
||||||
pub struct Linker {
|
pub struct ToLinker {
|
||||||
cache: PathBuf,
|
cache: PathBuf,
|
||||||
key: Option<String>,
|
key: Option<String>,
|
||||||
read: usize,
|
read: usize,
|
||||||
pub(crate) linker: symlink::AsyncLinker,
|
pub(crate) linker: linkto::AsyncToLinker,
|
||||||
opts: WriteOpts,
|
opts: WriteOpts,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncRead for Linker {
|
impl AsyncRead for ToLinker {
|
||||||
#[cfg(feature = "async-std")]
|
#[cfg(feature = "async-std")]
|
||||||
fn poll_read(
|
fn poll_read(
|
||||||
mut self: Pin<&mut Self>,
|
mut self: Pin<&mut Self>,
|
||||||
|
|
@ -248,7 +253,7 @@ fn filesize(target: &Path) -> Result<usize> {
|
||||||
.len() as usize)
|
.len() as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Linker {
|
impl ToLinker {
|
||||||
/// Creates a new asynchronous readable file handle into the cache.
|
/// Creates a new asynchronous readable file handle into the cache.
|
||||||
pub async fn open<P, K, T>(cache: P, key: K, target: T) -> Result<Self>
|
pub async fn open<P, K, T>(cache: P, key: K, target: T) -> Result<Self>
|
||||||
where
|
where
|
||||||
|
|
@ -256,12 +261,12 @@ impl Linker {
|
||||||
K: AsRef<str>,
|
K: AsRef<str>,
|
||||||
T: AsRef<Path>,
|
T: AsRef<Path>,
|
||||||
{
|
{
|
||||||
async fn inner(cache: &Path, key: &str, target: &Path) -> Result<Linker> {
|
async fn inner(cache: &Path, key: &str, target: &Path) -> Result<ToLinker> {
|
||||||
let size = filesize(&target)?;
|
let size = filesize(target)?;
|
||||||
WriteOpts::new()
|
WriteOpts::new()
|
||||||
.algorithm(Algorithm::Sha256)
|
.algorithm(Algorithm::Sha256)
|
||||||
.size(size)
|
.size(size)
|
||||||
.link(cache, key, target)
|
.link_to(cache, key, target)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
inner(cache.as_ref(), key.as_ref(), target.as_ref()).await
|
inner(cache.as_ref(), key.as_ref(), target.as_ref()).await
|
||||||
|
|
@ -273,20 +278,20 @@ impl Linker {
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
T: AsRef<Path>,
|
T: AsRef<Path>,
|
||||||
{
|
{
|
||||||
async fn inner(cache: &Path, target: &Path) -> Result<Linker> {
|
async fn inner(cache: &Path, target: &Path) -> Result<ToLinker> {
|
||||||
let size = filesize(&target)?;
|
let size = filesize(target)?;
|
||||||
WriteOpts::new()
|
WriteOpts::new()
|
||||||
.algorithm(Algorithm::Sha256)
|
.algorithm(Algorithm::Sha256)
|
||||||
.size(size)
|
.size(size)
|
||||||
.link_hash(cache, target)
|
.link_to_hash(cache, target)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
inner(cache.as_ref(), target.as_ref()).await
|
inner(cache.as_ref(), target.as_ref()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consumes the rest of the file handle, creates a symlink into the cache,
|
/// Consumes the rest of the file handle, creates an symlink into
|
||||||
/// and creates index entries for the linked file. Also verifies data
|
/// the cache, and creates index entries for the linked file. Also verifies
|
||||||
/// against `size` and `integrity` options, if provided. Must be called
|
/// data against `size` and `integrity` options, if provided. Must be called
|
||||||
/// manually in order to complete the writing process, otherwise everything
|
/// manually in order to complete the writing process, otherwise everything
|
||||||
/// will be thrown out.
|
/// will be thrown out.
|
||||||
pub async fn commit(mut self) -> Result<Integrity> {
|
pub async fn commit(mut self) -> Result<Integrity> {
|
||||||
|
|
@ -338,15 +343,15 @@ impl Linker {
|
||||||
///
|
///
|
||||||
/// Make sure to call `.commit()` when done reading to actually add the file
|
/// Make sure to call `.commit()` when done reading to actually add the file
|
||||||
/// to the cache.
|
/// to the cache.
|
||||||
pub struct SyncLinker {
|
pub struct SyncToLinker {
|
||||||
cache: PathBuf,
|
cache: PathBuf,
|
||||||
key: Option<String>,
|
key: Option<String>,
|
||||||
read: usize,
|
read: usize,
|
||||||
pub(crate) linker: symlink::Linker,
|
pub(crate) linker: linkto::ToLinker,
|
||||||
opts: WriteOpts,
|
opts: WriteOpts,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::io::Read for SyncLinker {
|
impl std::io::Read for SyncToLinker {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
let amt = self.linker.read(buf)?;
|
let amt = self.linker.read(buf)?;
|
||||||
self.read += amt;
|
self.read += amt;
|
||||||
|
|
@ -354,9 +359,9 @@ impl std::io::Read for SyncLinker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SyncLinker {
|
impl SyncToLinker {
|
||||||
/// Creates a new readable file handle to a file that will be linked into
|
/// Creates a new readable file handle to a file the cache will link to,
|
||||||
/// the cache, indexed at the provided key, on commit.
|
/// indexed at the provided key, on commit.
|
||||||
///
|
///
|
||||||
/// It is not necessary to read any of the file before calling `.commit()`.
|
/// It is not necessary to read any of the file before calling `.commit()`.
|
||||||
///
|
///
|
||||||
|
|
@ -366,7 +371,7 @@ impl SyncLinker {
|
||||||
///
|
///
|
||||||
/// fn main() -> cacache::Result<()> {
|
/// fn main() -> cacache::Result<()> {
|
||||||
/// let path = "../my-other-files/my-file.tgz";
|
/// let path = "../my-other-files/my-file.tgz";
|
||||||
/// let mut fd = cacache::SyncLinker::open("./my-cache", "my-key", path)?;
|
/// let mut fd = cacache::SyncToLinker::open("./my-cache", "my-key", path)?;
|
||||||
/// let mut str = String::new();
|
/// let mut str = String::new();
|
||||||
/// fd.read_to_string(&mut str).expect("Failed to read to string");
|
/// fd.read_to_string(&mut str).expect("Failed to read to string");
|
||||||
/// // The file is not linked into the cache until you commit it.
|
/// // The file is not linked into the cache until you commit it.
|
||||||
|
|
@ -380,18 +385,18 @@ impl SyncLinker {
|
||||||
K: AsRef<str>,
|
K: AsRef<str>,
|
||||||
T: AsRef<Path>,
|
T: AsRef<Path>,
|
||||||
{
|
{
|
||||||
fn inner(cache: &Path, key: &str, target: &Path) -> Result<SyncLinker> {
|
fn inner(cache: &Path, key: &str, target: &Path) -> Result<SyncToLinker> {
|
||||||
let size = filesize(&target)?;
|
let size = filesize(target)?;
|
||||||
WriteOpts::new()
|
WriteOpts::new()
|
||||||
.algorithm(Algorithm::Sha256)
|
.algorithm(Algorithm::Sha256)
|
||||||
.size(size)
|
.size(size)
|
||||||
.link_sync(cache, key, target)
|
.link_to_sync(cache, key, target)
|
||||||
}
|
}
|
||||||
inner(cache.as_ref(), key.as_ref(), target.as_ref())
|
inner(cache.as_ref(), key.as_ref(), target.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new readable file handle to a file that will be linked into
|
/// Creates a new readable file handle to a file that the cache will link
|
||||||
/// the cache, without an indexe key, on commit.
|
/// to, without an indexe key, on commit.
|
||||||
///
|
///
|
||||||
/// It is not necessary to read any of the file before calling `.commit()`.
|
/// It is not necessary to read any of the file before calling `.commit()`.
|
||||||
///
|
///
|
||||||
|
|
@ -401,7 +406,7 @@ impl SyncLinker {
|
||||||
///
|
///
|
||||||
/// fn main() -> cacache::Result<()> {
|
/// fn main() -> cacache::Result<()> {
|
||||||
/// let path = "../my-other-files/my-file.tgz";
|
/// let path = "../my-other-files/my-file.tgz";
|
||||||
/// let mut fd = cacache::SyncLinker::open_hash("./my-cache", path)?;
|
/// let mut fd = cacache::SyncToLinker::open_hash("./my-cache", path)?;
|
||||||
/// let mut str = String::new();
|
/// let mut str = String::new();
|
||||||
/// fd.read_to_string(&mut str).expect("Failed to read to string");
|
/// fd.read_to_string(&mut str).expect("Failed to read to string");
|
||||||
/// // The file is not linked into the cache until you commit it.
|
/// // The file is not linked into the cache until you commit it.
|
||||||
|
|
@ -414,21 +419,21 @@ impl SyncLinker {
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
T: AsRef<Path>,
|
T: AsRef<Path>,
|
||||||
{
|
{
|
||||||
fn inner(cache: &Path, target: &Path) -> Result<SyncLinker> {
|
fn inner(cache: &Path, target: &Path) -> Result<SyncToLinker> {
|
||||||
let size = filesize(&target)?;
|
let size = filesize(target)?;
|
||||||
WriteOpts::new()
|
WriteOpts::new()
|
||||||
.algorithm(Algorithm::Sha256)
|
.algorithm(Algorithm::Sha256)
|
||||||
.size(size)
|
.size(size)
|
||||||
.link_hash_sync(cache, target)
|
.link_to_hash_sync(cache, target)
|
||||||
}
|
}
|
||||||
inner(cache.as_ref(), target.as_ref())
|
inner(cache.as_ref(), target.as_ref())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consumes the rest of the file handle, creates a symlink into the cache,
|
/// Consumes the rest of the file handle, creates a symlink to the file, and
|
||||||
/// and creates index entries for the linked file. Also verifies data
|
/// creates index entries for the linked file. Also verifies data against
|
||||||
/// against `size` and `integrity` options, if provided. Must be called
|
/// `size` and `integrity` options, if provided. Must be called manually in
|
||||||
/// manually in order to complete the writing process, otherwise everything
|
/// order to complete the writing process, otherwise everything will be
|
||||||
/// will be thrown out.
|
/// thrown out.
|
||||||
pub fn commit(mut self) -> Result<Integrity> {
|
pub fn commit(mut self) -> Result<Integrity> {
|
||||||
self.consume()?;
|
self.consume()?;
|
||||||
let cache = self.cache;
|
let cache = self.cache;
|
||||||
|
|
@ -501,46 +506,46 @@ mod tests {
|
||||||
|
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let dir = tmp.path().to_owned();
|
let dir = tmp.path().to_owned();
|
||||||
crate::link(&dir, "my-key", target).await.unwrap();
|
crate::link_to(&dir, "my-key", target).await.unwrap();
|
||||||
|
|
||||||
let buf = crate::read(&dir, "my-key").await.unwrap();
|
let buf = crate::read(&dir, "my-key").await.unwrap();
|
||||||
assert_eq!(buf, b"hello world");
|
assert_eq!(buf, b"hello world");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_test]
|
#[async_test]
|
||||||
async fn test_link_hash() {
|
async fn test_link_to_hash() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let target = create_tmpfile(&tmp, b"hello world");
|
let target = create_tmpfile(&tmp, b"hello world");
|
||||||
|
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let dir = tmp.path().to_owned();
|
let dir = tmp.path().to_owned();
|
||||||
let sri = crate::link_hash(&dir, target).await.unwrap();
|
let sri = crate::link_to_hash(&dir, target).await.unwrap();
|
||||||
|
|
||||||
let buf = crate::read_hash(&dir, &sri).await.unwrap();
|
let buf = crate::read_hash(&dir, &sri).await.unwrap();
|
||||||
assert_eq!(buf, b"hello world");
|
assert_eq!(buf, b"hello world");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_link_sync() {
|
fn test_link_to_sync() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let target = create_tmpfile(&tmp, b"hello world");
|
let target = create_tmpfile(&tmp, b"hello world");
|
||||||
|
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let dir = tmp.path().to_owned();
|
let dir = tmp.path().to_owned();
|
||||||
crate::link_sync(&dir, "my-key", target).unwrap();
|
crate::link_to_sync(&dir, "my-key", target).unwrap();
|
||||||
|
|
||||||
let buf = crate::read_sync(&dir, "my-key").unwrap();
|
let buf = crate::read_sync(&dir, "my-key").unwrap();
|
||||||
assert_eq!(buf, b"hello world");
|
assert_eq!(buf, b"hello world");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_link_hash_sync() {
|
fn test_link_to_hash_sync() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let target = create_tmpfile(&tmp, b"hello world");
|
let target = create_tmpfile(&tmp, b"hello world");
|
||||||
|
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let dir = tmp.path().to_owned();
|
let dir = tmp.path().to_owned();
|
||||||
let sri = crate::link_hash_sync(&dir, target).unwrap();
|
let sri = crate::link_to_hash_sync(&dir, target).unwrap();
|
||||||
|
|
||||||
let buf = crate::read_hash_sync(&dir, &sri).unwrap();
|
let buf = crate::read_hash_sync(&dir, &sri).unwrap();
|
||||||
assert_eq!(buf, b"hello world");
|
assert_eq!(buf, b"hello world");
|
||||||
|
|
@ -553,7 +558,7 @@ mod tests {
|
||||||
|
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let dir = tmp.path().to_owned();
|
let dir = tmp.path().to_owned();
|
||||||
let mut handle = crate::Linker::open(&dir, "my-key", target).await.unwrap();
|
let mut handle = crate::ToLinker::open(&dir, "my-key", target).await.unwrap();
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
handle.read_to_end(&mut buf).await.unwrap();
|
handle.read_to_end(&mut buf).await.unwrap();
|
||||||
|
|
@ -571,7 +576,7 @@ mod tests {
|
||||||
|
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let dir = tmp.path().to_owned();
|
let dir = tmp.path().to_owned();
|
||||||
let mut handle = crate::Linker::open_hash(&dir, target).await.unwrap();
|
let mut handle = crate::ToLinker::open_hash(&dir, target).await.unwrap();
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
handle.read_to_end(&mut buf).await.unwrap();
|
handle.read_to_end(&mut buf).await.unwrap();
|
||||||
|
|
@ -589,7 +594,7 @@ mod tests {
|
||||||
|
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let dir = tmp.path().to_owned();
|
let dir = tmp.path().to_owned();
|
||||||
let mut handle = crate::SyncLinker::open(&dir, "my-key", target).unwrap();
|
let mut handle = crate::SyncToLinker::open(&dir, "my-key", target).unwrap();
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
handle.read_to_end(&mut buf).unwrap();
|
handle.read_to_end(&mut buf).unwrap();
|
||||||
|
|
@ -607,7 +612,7 @@ mod tests {
|
||||||
|
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
let dir = tmp.path().to_owned();
|
let dir = tmp.path().to_owned();
|
||||||
let mut handle = crate::SyncLinker::open_hash(&dir, target).unwrap();
|
let mut handle = crate::SyncToLinker::open_hash(&dir, target).unwrap();
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
handle.read_to_end(&mut buf).unwrap();
|
handle.read_to_end(&mut buf).unwrap();
|
||||||
Loading…
Reference in New Issue