use std::fs::File;
use std::io::Write;
use std::path::Path;
use anyhow::Result;
use hex::FromHex;
use crate::reader::{MmapMosaicReader, MosaicReaderError};
use crate::IdxDescription;
fn write_file(key: &String, content: &[u8]) -> Result<()> {
let mut file = File::create(key)?;
file.write_all(content)?;
Ok(())
}
pub fn extract(
filename: &Path,
index: &IdxDescription,
keys: &Vec<String>,
all: &bool,
) -> Result<()> {
let reader = match MmapMosaicReader::new(filename, *index) {
Ok(reader) => reader,
Err(error) => match error.downcast_ref::<MosaicReaderError>() {
Some(MosaicReaderError::IndexNotFound { idx_description }) => panic!(
"Cannot find index {},
maybe it does not exist in this file. Use `info` to list available indexes.",
idx_description
),
_ => return Err(error),
},
};
if *all {
for pair in reader.iter() {
let (key, content) = pair?;
let key_hex = hex::encode(key);
if let Err(error) = write_file(&key_hex, &content) {
println!("Error while writing object {}: {}", key_hex, error);
}
}
} else {
for k in keys {
let key = match <Vec<u8>>::from_hex(k) {
Ok(slice) => slice,
Err(_) => {
println!("Skipping malformed hex key: {}", k);
continue;
}
};
let cnt = match reader.lookup(&key) {
Ok(o) => match o {
Some(object) => object,
None => {
println!("Skipping key not found: {}", k);
continue;
}
},
Err(_) => {
println!("Skipping key not found: {}", k);
continue;
}
};
if let Err(error) = write_file(k, &cnt) {
println!("Error while writing object {}: {}", k, error);
}
}
}
Ok(())
}