vbump 0.5.1

Bumps the version of a project, creating the appropiate git tags
Documentation
use std::str::FromStr;

use semver::Version;
use clap::ArgEnum;
use thiserror::Error;

pub mod handlers;
pub mod detect;

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ArgEnum)]
pub enum Level {
    Major,
    Minor,
    Patch,
}

impl FromStr for Level {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(match s {
            "major" => Level::Major,
            "minor" => Level::Minor,
            "patch" => Level::Patch,
            _ => return Err(()),
        })
    }
}

#[derive(Debug, Error)]
pub(crate) enum VersionError {
    #[error("Could not parse version string: {0}")]
    ParseError(String),

    #[error("Specified file does not contain a version field")]
    NoVersionField,

    #[error("Version field in Cargo.toml is not a string (and should be)")]
    CargoVersionNotString,

    #[error("Cargo.toml must be a table (have keys and values)")]
    CargoNotATable,

    #[error("Cargo.toml must have a [package] section")]
    CargoWithoutPackage,

    #[error("Carto.toml's package section must be a table (have keys and values)")]
    CargoPackageNotATable,

    #[error("You didn't provide a file and the current repository does not contain any tag matching v[X[.Y[.Z]]]")]
    NoGitTags,
}

pub(crate) fn parse_version(string: &str) -> Result<Version, VersionError> {
    string.parse().map_err(|_| VersionError::ParseError(string.to_string()))
}

pub(crate) fn upgrade_version(current: Version, level: Level) -> Version {
    let mut version = current;

    match level {
        Level::Major => version.increment_major(),
        Level::Minor => version.increment_minor(),
        Level::Patch => version.increment_patch(),
    }

    version
}