mirror of https://github.com/zkat/cacache-rs.git
Merge 76a859f2cc into 105692a4da
This commit is contained in:
commit
08efe54358
|
|
@ -19,9 +19,10 @@ hex = "0.4.3"
|
||||||
memmap2 = { version = "0.5.8", optional = true }
|
memmap2 = { version = "0.5.8", optional = true }
|
||||||
miette = "5.7.0"
|
miette = "5.7.0"
|
||||||
reflink-copy = "0.1.9"
|
reflink-copy = "0.1.9"
|
||||||
serde = "1.0.130"
|
serde = { version = "1.0.130", features = ["derive"] }
|
||||||
serde_derive = "1.0.130"
|
|
||||||
serde_json = "1.0.68"
|
serde_json = "1.0.68"
|
||||||
|
base64 = "0.22.0"
|
||||||
|
base64-serde = "0.7.0"
|
||||||
sha1 = "0.10.5"
|
sha1 = "0.10.5"
|
||||||
sha2 = "0.10.6"
|
sha2 = "0.10.6"
|
||||||
ssri = "9.0.0"
|
ssri = "9.0.0"
|
||||||
|
|
|
||||||
94
src/index.rs
94
src/index.rs
|
|
@ -11,20 +11,22 @@ use digest::Digest;
|
||||||
use either::{Left, Right};
|
use either::{Left, Right};
|
||||||
#[cfg(any(feature = "async-std", feature = "tokio"))]
|
#[cfg(any(feature = "async-std", feature = "tokio"))]
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use sha1::Sha1;
|
use sha1::Sha1;
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
use ssri::Integrity;
|
use ssri::Integrity;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
|
use base64_serde::base64_serde_type;
|
||||||
|
|
||||||
#[cfg(any(feature = "async-std", feature = "tokio"))]
|
#[cfg(any(feature = "async-std", feature = "tokio"))]
|
||||||
use crate::async_lib::{AsyncBufReadExt, AsyncWriteExt};
|
use crate::async_lib::{AsyncBufReadExt, AsyncWriteExt};
|
||||||
use crate::content::path::content_path;
|
use crate::content::path::content_path;
|
||||||
use crate::errors::{IoErrorExt, Result};
|
use crate::errors::{IoErrorExt, Result};
|
||||||
use crate::put::WriteOpts;
|
use crate::put::WriteOpts;
|
||||||
|
|
||||||
const INDEX_VERSION: &str = "5";
|
const INDEX_VERSION: &str = "6";
|
||||||
|
|
||||||
/// Represents a cache index entry, which points to content.
|
/// Represents a cache index entry, which points to content.
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
|
|
@ -50,9 +52,39 @@ struct SerializableMetadata {
|
||||||
time: u128,
|
time: u128,
|
||||||
size: usize,
|
size: usize,
|
||||||
metadata: Value,
|
metadata: Value,
|
||||||
|
#[serde(with = "option_base64")]
|
||||||
raw_metadata: Option<Vec<u8>>,
|
raw_metadata: Option<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base64_serde_type!(Base64Standard, base64::engine::general_purpose::STANDARD);
|
||||||
|
|
||||||
|
mod option_base64 {
|
||||||
|
use super::Base64Standard;
|
||||||
|
use serde::{Deserialize, Deserializer, Serializer};
|
||||||
|
|
||||||
|
pub fn serialize<S>(data: &Option<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
match data {
|
||||||
|
Some(data) => Base64Standard::serialize(data, serializer),
|
||||||
|
None => serializer.serialize_none(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
// Create a wrapper type to reuse existing "with" attribute easily
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct WrappedVecU8(#[serde(with = "Base64Standard")] Vec<u8>);
|
||||||
|
|
||||||
|
Option::<WrappedVecU8>::deserialize(deserializer)
|
||||||
|
.map(|it| it.map(|wrapped_value| wrapped_value.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq for SerializableMetadata {
|
impl PartialEq for SerializableMetadata {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.key == other.key
|
self.key == other.key
|
||||||
|
|
@ -590,6 +622,64 @@ mod tests {
|
||||||
assert!(!content.exists());
|
assert!(!content.exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_json_raw_metadata() {
|
||||||
|
let meta = SerializableMetadata {
|
||||||
|
key: "hello".to_string(),
|
||||||
|
integrity: Some("sha1-deadbeef".to_string()),
|
||||||
|
time: 0,
|
||||||
|
size: 0,
|
||||||
|
metadata: json!(null),
|
||||||
|
raw_metadata: Some(vec![b'1', b'2', b'3', b'4']),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
serde_json::to_string(&meta).unwrap(),
|
||||||
|
"{\"key\":\"hello\",\"integrity\":\"sha1-deadbeef\",\"time\":0,\"size\":0,\"metadata\":null,\"raw_metadata\":\"MTIzNA==\"}"
|
||||||
|
);
|
||||||
|
|
||||||
|
let value = json!(
|
||||||
|
{
|
||||||
|
"key": "hello",
|
||||||
|
"integrity": "sha1-deadbeef",
|
||||||
|
"time": 0,
|
||||||
|
"size": 0,
|
||||||
|
"metadata": null,
|
||||||
|
"raw_metadata": "MTIzNA=="
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
let de_meta: SerializableMetadata = serde_json::from_value(value).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(de_meta, meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn raw_metadata() {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let dir = tmp.path().to_owned();
|
||||||
|
let sri: Integrity = "sha1-deadbeef".parse().unwrap();
|
||||||
|
let time = 1_234_567;
|
||||||
|
let raw_metadata = vec![1, 2, 3, 4];
|
||||||
|
let opts = WriteOpts::new()
|
||||||
|
.integrity(sri.clone())
|
||||||
|
.time(time)
|
||||||
|
.raw_metadata(raw_metadata.clone());
|
||||||
|
insert(&dir, "hello", opts).unwrap();
|
||||||
|
let entry = find(&dir, "hello").unwrap().unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
entry,
|
||||||
|
Metadata {
|
||||||
|
key: String::from("hello"),
|
||||||
|
integrity: sri,
|
||||||
|
time: time,
|
||||||
|
size: 0,
|
||||||
|
metadata: json!(null),
|
||||||
|
raw_metadata: Some(raw_metadata),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn round_trip() {
|
fn round_trip() {
|
||||||
let tmp = tempfile::tempdir().unwrap();
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue