use toml_edit::{
Document,
Formatted,
Item,
Value,
value,
};
use semver::{
Version,
Prerelease,
};
use anyhow::bail;
pub struct Manifest {
path: String,
doc: Option< Document >,
}
impl Manifest {
pub fn new( path: &str ) -> Self {
Self {
path: path.to_owned(),
doc: None,
}
}
pub fn load( &mut self ) -> anyhow::Result<()> {
let toml = std::fs::read_to_string( &self.path )?;
let doc = match toml.parse::<Document>(){
Ok( doc ) => doc,
Err( e ) => bail!( "Couldn't load manifest from >>{}<< {}", &self.path, &e ),
};
self.doc = Some( doc );
Ok(())
}
pub fn save( &mut self ) -> anyhow::Result<()> {
if let Some( doc ) = &self.doc {
std::fs::write( &self.path, doc.to_string() ).unwrap();
}
Ok(())
}
fn get_formatted_version( &self ) -> anyhow::Result<Formatted< String >> {
if let Some( doc ) = &self.doc {
let fs = match &doc["package"]["version"] {
Item::Value( Value::String( s ) ) => s, _ => bail!("Unsupported version format!"),
};
Ok( fs.clone() )
} else {
bail!("No manifest loaded!");
}
}
pub fn get_version( &self ) -> anyhow::Result<Version> {
let fs = self.get_formatted_version()?;
let v = fs.value();
let version = Version::parse(&v).unwrap();
return Ok( version );
}
pub fn get_pretty_version( &self ) -> anyhow::Result<String> {
let v = self.get_version()?;
Ok( v.to_string() )
}
pub fn set_version( &mut self, version: &Version ) -> anyhow::Result<()>{
let fs = self.get_formatted_version()?;
if let Some( doc ) = &mut self.doc {
let mut ni = value( version.to_string() );
match &mut ni {
Item::Value( Value::String( s ) ) => {
let d = s.decor_mut();
let od = fs.decor();
match ( od.prefix(), od.suffix() ) {
( Some( p ), Some( s ) ) => {
d.set_prefix( p );
d.set_suffix( s );
},
_ => {},
}
},
_ => {},
}
doc[ "package" ][ "version" ] = ni;
} else {
bail!("No manifest loaded!");
}
Ok(())
}
pub fn bump_patch_version( &mut self ) -> anyhow::Result<()> {
let old_version = self.get_version()?;
let mut new_version = old_version.clone();
new_version.patch = old_version.patch + 1;
self.set_version( &new_version )?;
Ok(())
}
pub fn bump_minor_version( &mut self ) -> anyhow::Result<()> {
let old_version = self.get_version()?;
let mut new_version = old_version.clone();
new_version.patch = 0;
new_version.minor = old_version.minor + 1;
self.set_version( &new_version )?;
Ok(())
}
pub fn bump_major_version( &mut self ) -> anyhow::Result<()> {
let old_version = self.get_version()?;
let mut new_version = old_version.clone();
new_version.patch = 0;
new_version.minor = 0;
new_version.major = old_version.major + 1;
self.set_version( &new_version )?;
Ok(())
}
pub fn set_version_suffix(&mut self, suffix: &str ) -> anyhow::Result<()> {
let old_version = self.get_version()?;
let mut new_version = old_version.clone();
new_version.pre = Prerelease::new( suffix ).unwrap();
self.set_version( &new_version )?;
Ok(())
}
}