rvcs 0.1.0

A rusty version control system.
Documentation
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(())
}