use mr_bundle::{
resource_id_for_path, Bundle, FileSystemBundler, Manifest, ResourceBytes, ResourceIdentifier,
};
use std::collections::HashMap;
use std::path::PathBuf;
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(tag = "manifest_version")]
#[allow(missing_docs)]
enum TestManifest {
#[serde(rename = "0")]
V0(ManifestV0),
}
impl Manifest for TestManifest {
fn generate_resource_ids(&mut self) -> HashMap<ResourceIdentifier, String> {
let mut out = HashMap::new();
match self {
Self::V0(manifest) => {
for thing in &mut manifest.things {
let id = resource_id_for_path(&thing.location).unwrap();
out.insert(id.clone(), thing.location.clone());
thing.location = id;
}
}
}
out
}
fn resource_ids(&self) -> Vec<ResourceIdentifier> {
match self {
Self::V0(manifest) => manifest
.things
.iter()
.map(|b| resource_id_for_path(&b.location).unwrap())
.collect(),
}
}
#[cfg(feature = "fs")]
fn file_name() -> &'static str {
"test-manifest.yaml"
}
#[cfg(feature = "fs")]
fn bundle_extension() -> &'static str {
"bundle"
}
}
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
struct ManifestV0 {
name: String,
things: Vec<ThingManifest>,
}
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
struct ThingManifest {
location: String,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
struct Thing(String);
impl From<Thing> for ResourceBytes {
fn from(thing: Thing) -> Self {
ResourceBytes::from(thing.0.as_bytes().to_vec())
}
}
#[tokio::test]
async fn file_system_bundler() {
let dir = tempfile::tempdir().unwrap();
let resource: ResourceBytes = Thing("some content".into()).into();
let resource_path = PathBuf::from("another/nested/bundled.thing");
tokio::fs::create_dir_all(dir.path().join(resource_path.parent().unwrap()))
.await
.unwrap();
tokio::fs::write(dir.path().join(&resource_path), resource)
.await
.unwrap();
let manifest = TestManifest::V0(ManifestV0 {
name: "name".to_string(),
things: vec![ThingManifest {
location: resource_path.to_str().unwrap().to_string(),
}],
});
let manifest_path = dir.path().join(TestManifest::file_name());
tokio::fs::write(&manifest_path, serde_yaml::to_string(&manifest).unwrap())
.await
.unwrap();
let bundle_path = dir
.path()
.join(format!("test-bundle.{}", TestManifest::bundle_extension()));
FileSystemBundler::bundle_to::<TestManifest>(manifest_path, bundle_path)
.await
.unwrap();
let bundle_bytes = tokio::fs::read(
dir.path()
.join(format!("test-bundle.{}", TestManifest::bundle_extension())),
)
.await
.unwrap();
let bundle = Bundle::<TestManifest>::unpack(bundle_bytes.as_slice()).unwrap();
let unpacked_dir = dir.path().join("unpacked");
FileSystemBundler::expand_to(&bundle, &unpacked_dir, false)
.await
.unwrap();
assert!(unpacked_dir.join(TestManifest::file_name()).is_file());
assert!(unpacked_dir.join("bundled.thing").is_file());
let manifest_path = unpacked_dir.join(TestManifest::file_name());
let rebundle = FileSystemBundler::bundle::<TestManifest>(manifest_path)
.await
.unwrap();
let rebundle_bytes = rebundle.pack().unwrap();
assert_eq!(bundle_bytes, rebundle_bytes);
}
#[tokio::test]
async fn file_system_bundler_with_raw_bundle() {
let dir = tempfile::tempdir().unwrap();
let resource: ResourceBytes = Thing("some content".into()).into();
let resource_path = PathBuf::from("another/nested/bundled.thing");
tokio::fs::create_dir_all(dir.path().join(resource_path.parent().unwrap()))
.await
.unwrap();
tokio::fs::write(dir.path().join(&resource_path), resource)
.await
.unwrap();
let mut manifest = TestManifest::V0(ManifestV0 {
name: "name".to_string(),
things: vec![ThingManifest {
location: resource_path.to_str().unwrap().to_string(),
}],
});
let manifest_path = dir.path().join(TestManifest::file_name());
tokio::fs::write(&manifest_path, serde_yaml::to_string(&manifest).unwrap())
.await
.unwrap();
let bundle_path = dir
.path()
.join(format!("test-bundle.{}", TestManifest::bundle_extension()));
FileSystemBundler::bundle_to::<TestManifest>(manifest_path, &bundle_path)
.await
.unwrap();
let bundle_bytes = tokio::fs::read(
dir.path()
.join(format!("test-bundle.{}", TestManifest::bundle_extension())),
)
.await
.unwrap();
let bundle = Bundle::<serde_yaml::Value>::unpack(bundle_bytes.as_slice()).unwrap();
let unpacked_dir = dir.path().join("unpacked");
FileSystemBundler::expand_named_to(&bundle, "unknown.yaml", &unpacked_dir, false)
.await
.unwrap();
assert!(unpacked_dir.join("unknown.yaml").is_file());
manifest.generate_resource_ids();
assert_eq!(
serde_yaml::to_string(&manifest).unwrap(),
std::fs::read_to_string(unpacked_dir.join("unknown.yaml")).unwrap()
);
assert!(unpacked_dir.join("bundled.thing").is_file());
assert_eq!(
"some content",
std::fs::read_to_string(unpacked_dir.join("bundled.thing")).unwrap()
);
}