use crate::errors::BumperError; use cargo_edit::Manifest; use log::{debug, info}; use std::path::{Path, PathBuf}; use toml_edit::{Item, Value}; pub struct Rust { dirname: PathBuf, cargo_toml: CargoToml, } impl Rust { pub fn new(dirname: &Path) -> Result { let cargo_toml = dirname.join("Cargo.toml"); if cargo_toml.exists() { return Ok(Self { dirname: dirname.to_path_buf(), cargo_toml: CargoToml::parse(&cargo_toml)?, }); } Err(BumperError::UnknownProjectKind(dirname.to_path_buf())) } pub fn set_version(&mut self, version: &str) -> Result<(), BumperError> { debug!("parsing Cargo.toml from {}", self.dirname.display()); // debug!("Cargo.toml:\n{:#?}", self.cargo_toml); self.cargo_toml.set_version(version)?; self.cargo_toml.write()?; info!( "Rust project {}, in {}, version set to {}", self.dirname.display(), "xxx", version ); Ok(()) } } #[derive(Debug)] struct CargoToml { dirname: PathBuf, manifest: Manifest, } impl CargoToml { fn parse(dirname: &Path) -> Result { let manifest = Manifest::open(&Some(dirname.to_path_buf())) .map_err(|err| BumperError::FromToml(dirname.to_path_buf(), err))?; Ok(Self { dirname: dirname.to_path_buf(), manifest, }) } fn write(&self) -> Result<(), BumperError> { debug!("saving Cargo.toml to {}", self.dirname.display()); let mut file = Manifest::find_file(&Some(self.dirname.to_path_buf())) .map_err(|err| BumperError::CargoTomlNotFound(self.dirname.to_path_buf(), err))?; self.manifest .write_to_file(&mut file) .map_err(|err| BumperError::WriteToml(self.dirname.to_path_buf(), err))?; Ok(()) } fn set_version(&mut self, version: &str) -> Result<(), BumperError> { let package = self .manifest .get_table(&["package".to_string()]) .map_err(BumperError::NoPackage)?; if let Some(package) = package.as_table_mut() { debug!("setting Cargo.toml set version to {} in memory", version); let v = package.entry("version"); *v = Item::Value(Value::from(version)); } else { return Err(BumperError::ProjectNotTable); } Ok(()) } }