Skip to content
pub fn bump_version(version: &str, mode: &str) -> Result<String, Box<dyn std::error::Error>> {
    let parts: Vec<&str> = version.split('.').collect();

    if parts.len() != 3 {
        return Err(format!(
            "Invalid version format: {}. Expected semver format (x.y.z)",
            version
        )
        .into());
    }

    let major: u64 = parts[0].parse()?;
    let minor: u64 = parts[1].parse()?;
    let patch: u64 = parts[2].parse()?;

    let new_version = match mode {
        "alpha" => {
            format!("{}.{}.{}", major, minor, patch + 1)
        }
        "beta" => {
            format!("{}.{}.{}", major, minor + 1, 0)
        }
        "normal" => {
            format!("{}.{}.{}", major, minor, patch + 1)
        }
        _ => {
            return Err(format!("Invalid mode: {}. Use 'alpha', 'beta', or 'normal'", mode).into());
        }
    };

    Ok(new_version)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_bump_version_alpha() {
        assert_eq!(bump_version("1.2.3", "alpha").unwrap(), "1.2.4");
        assert_eq!(bump_version("0.0.0", "alpha").unwrap(), "0.0.1");
        assert_eq!(bump_version("10.20.99", "alpha").unwrap(), "10.20.100");
    }

    #[test]
    fn test_bump_version_beta() {
        assert_eq!(bump_version("1.2.3", "beta").unwrap(), "1.3.0");
        assert_eq!(bump_version("0.0.5", "beta").unwrap(), "0.1.0");
        assert_eq!(bump_version("2.9.99", "beta").unwrap(), "2.10.0");
    }

    #[test]
    fn test_bump_version_normal() {
        assert_eq!(bump_version("1.2.3", "normal").unwrap(), "1.2.4");
        assert_eq!(bump_version("0.0.0", "normal").unwrap(), "0.0.1");
        assert_eq!(bump_version("5.10.0", "normal").unwrap(), "5.10.1");
    }

    #[test]
    fn test_bump_version_invalid_format() {
        assert!(bump_version("1.2", "alpha").is_err());
        assert!(bump_version("1.2.3.4", "alpha").is_err());
        assert!(bump_version("not-a-version", "alpha").is_err());
    }

    #[test]
    fn test_bump_version_invalid_mode() {
        assert!(bump_version("1.2.3", "invalid").is_err());
        assert!(bump_version("1.2.3", "").is_err());
    }
}