vbump 0.5.1

Bumps the version of a project, creating the appropiate git tags
Documentation
use std::path::{Path, PathBuf};
use std::io::{Read, Write};
use std::fs::File;
use std::process::Command;

use semver::Version;
use anyhow::Result;

use crate::{Level, VersionError, parse_version, upgrade_version};

pub fn handle(filename: &Path, level: Level, fake: bool) -> Result<(Version, Vec<PathBuf>)> {
    eprintln!("Detected rust project: Cargo.toml");
    let cwd = filename.parent().unwrap().canonicalize()?;
    let mut tomlfile = File::open(filename)?;
    let mut buff = String::new();

    tomlfile.read_to_string(&mut buff)?;

    let mut contents: toml::Value = toml::from_str(&buff)?;

    let new_ver = contents.as_table_mut().map(|t| {
        t.get_mut("package").map(|p| {
            p.as_table_mut().map(|p| {
                let old_ver = p.remove("version").ok_or(VersionError::NoVersionField)?;
                let old_ver = old_ver.as_str().ok_or(VersionError::CargoVersionNotString)?;
                let new_ver = upgrade_version(parse_version(old_ver)?, level);

                p.insert("version".into(), toml::Value::String(new_ver.to_string()));

                Ok::<_, VersionError>(new_ver)
            })
        })
    }).ok_or(VersionError::CargoNotATable)?.ok_or(VersionError::CargoWithoutPackage)?.ok_or(VersionError::CargoPackageNotATable)??;

    if !fake {
        let output = toml::to_string(&contents)?;
        let mut file = File::create(filename)?;

        file.write_all(output.as_bytes())?;

        Command::new("cargo").current_dir(cwd).args(["check"]).output()?;
    }

    Ok((new_ver, vec![filename.into(), filename.parent().unwrap().join("Cargo.lock")]))
}