use crate::io::FileIO;
use crate::spec::manifest_entry::ManifestEntry;
use crate::spec::manifest_entry::MANIFEST_ENTRY_SCHEMA;
use crate::Result;
pub struct Manifest;
impl Manifest {
pub async fn read(file_io: &FileIO, path: &str) -> Result<Vec<ManifestEntry>> {
let input_file = file_io.new_input(path)?;
if !input_file.exists().await? {
return Ok(Vec::new());
}
let content = input_file.read().await?;
Self::read_from_bytes(&content)
}
fn read_from_bytes(bytes: &[u8]) -> Result<Vec<ManifestEntry>> {
crate::spec::from_avro_bytes(bytes)
}
pub async fn write(file_io: &FileIO, path: &str, entries: &[ManifestEntry]) -> Result<()> {
let bytes = crate::spec::to_avro_bytes(MANIFEST_ENTRY_SCHEMA, entries)?;
let output = file_io.new_output(path)?;
output.write(bytes::Bytes::from(bytes)).await
}
}
#[cfg(test)]
#[cfg(not(windows))] mod tests {
use super::*;
use crate::io::FileIO;
use crate::spec::manifest_common::FileKind;
use std::env::current_dir;
#[tokio::test]
async fn test_read_manifest_from_file() {
let workdir = current_dir().unwrap();
let path =
workdir.join("tests/fixtures/manifest/manifest-8ded1f09-fcda-489e-9167-582ac0f9f846-0");
let file_io = FileIO::from_url("file://").unwrap().build().unwrap();
let entries = Manifest::read(&file_io, path.to_str().unwrap())
.await
.unwrap();
assert_eq!(entries.len(), 2);
let t1 = &entries[0];
assert_eq!(t1.kind(), &FileKind::Delete);
assert_eq!(t1.bucket(), 1);
let t2 = &entries[1];
assert_eq!(t2.kind(), &FileKind::Add);
assert_eq!(t2.bucket(), 2);
}
}