use flate2::{write::GzEncoder, Compression};
use sha2::{Digest, Sha256};
use crate::{error, in_repo};
use std::{
fs,
fs::File,
io,
io::{Read, Write},
path::Path,
};
pub fn add(file: &str) -> io::Result<()> {
if !in_repo() {
return Err(error!("Current folder is not a rvcs repository."));
}
if !Path::new(file).exists() {
return Err(error!(
(&format!("No file named `{}` in the current folder.", file))
));
}
if Path::new(file).is_dir() {
if file.contains(".rvcs") {
return Ok(());
}
let entries = fs::read_dir(file)?;
for entry in entries {
add(entry?.path().to_str().unwrap())?;
}
} else {
let mut content = vec![];
File::open(file)?.read_to_end(&mut content)?;
let mut hasher = Sha256::new();
hasher.update(&content);
let fname = format!("{:x}", hasher.finalize());
if Path::new(&format!(".rvcs/objects/{}", fname)).exists() {
return Ok(());
}
let mut compressor = GzEncoder::new(vec![], Compression::best());
compressor.write_all(&content)?;
let mut nfile = File::create(&format!(".rvcs/objects/{}", fname))?;
nfile.write_all(&compressor.finish()?)?;
if !Path::new(".rvcs/objects/links").exists() {
File::create(".rvcs/objects/links")?;
}
let mut flink = fs::OpenOptions::new()
.append(true)
.open(".rvcs/objects/links")?;
flink.write_all(format!("{}|{}\n", file, fname).as_bytes())?;
}
Ok(())
}