cargo-governor 2.0.0

Machine-First, LLM-Ready, CI/CD-Native release automation tool for Rust crates
Documentation
//! Cargo.toml operations for bump service

use crate::error::Result;
use std::fs;

/// Get workspace version from Cargo.toml value
pub fn get_workspace_version(value: &toml::Value) -> Result<String> {
    let package = value
        .get("workspace")
        .and_then(|w| w.get("package"))
        .or_else(|| value.get("package"));

    package
        .and_then(|p| p.get("version"))
        .and_then(|v| v.as_str())
        .map(String::from)
        .ok_or_else(|| crate::error::Error::Config("No version found in Cargo.toml".to_string()))
}

/// Update workspace version in Cargo.toml value
pub fn update_workspace_version(value: &mut toml::Value, new_version: &str) -> Result<()> {
    if let Some(workspace) = value.get_mut("workspace")
        && let Some(table) = workspace.as_table_mut()
        && let Some(pkg) = table.get_mut("package")
        && let Some(pkg_table) = pkg.as_table_mut()
        && let Some(ver) = pkg_table.get_mut("version")
    {
        *ver = toml::Value::String(new_version.to_string());
        return Ok(());
    }

    if let Some(pkg) = value.get_mut("package")
        && let Some(table) = pkg.as_table_mut()
        && let Some(ver) = table.get_mut("version")
    {
        *ver = toml::Value::String(new_version.to_string());
        return Ok(());
    }

    Err(crate::error::Error::Config(
        "No version found in Cargo.toml".to_string(),
    ))
}

/// Read and parse Cargo.toml
pub fn read_cargo_toml(workspace_path: &str) -> Result<(String, toml::Value)> {
    let cargo_toml_path = std::path::PathBuf::from(workspace_path).join("Cargo.toml");
    let content = fs::read_to_string(&cargo_toml_path)
        .map_err(|e| crate::error::Error::Io(format!("Failed to read Cargo.toml: {e}")))?;

    let value: toml::Value = toml::from_str(&content)
        .map_err(|e| crate::error::Error::Config(format!("Failed to parse Cargo.toml: {e}")))?;

    Ok((content, value))
}

/// Write updated Cargo.toml
pub fn write_cargo_toml(workspace_path: &str, value: &toml::Value) -> Result<()> {
    let cargo_toml_path = std::path::PathBuf::from(workspace_path).join("Cargo.toml");
    let updated_content = toml::to_string_pretty(value)
        .map_err(|e| crate::error::Error::Config(format!("Failed to serialize Cargo.toml: {e}")))?;

    fs::write(&cargo_toml_path, updated_content)
        .map_err(|e| crate::error::Error::Io(format!("Failed to write Cargo.toml: {e}")))?;

    Ok(())
}