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")]))
}