1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use semver::Version;
use std::{fs, io::Error as IoError, path::Path};
use thiserror::Error;
use toml_edit::{value, Document, Item, TomlError};
#[derive(Debug, Error)]
pub enum Error {
#[error("an io error occurred")]
IoError(#[from] IoError),
#[error("An error occurred during version parsing")]
SemverParseError(#[from] semver::SemVerError),
#[error("a parser error occurred")]
ParseError(#[from] TomlError),
#[error("the field {field:?} is not of type {ty:?}")]
InvalidFieldType { field: String, ty: String },
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SemVer {
Major,
Minor,
Patch,
}
pub fn get_version(path: impl AsRef<Path>) -> Result<Version, Error> {
let cargo_toml_content = fs::read_to_string(path.as_ref())?;
let doc = cargo_toml_content.parse::<Document>()?;
let item: &Item = &doc["package"]["version"];
if let Some(s) = item.as_str() {
Ok(Version::parse(s)?)
} else {
Err(Error::InvalidFieldType {
field: "version".to_string(),
ty: "string".to_string(),
})
}
}
pub fn set_version(path: impl AsRef<Path>, version: impl AsRef<str>) -> Result<(), Error> {
let cargo_toml_content = fs::read_to_string(path.as_ref())?;
let mut doc = cargo_toml_content.parse::<Document>()?;
doc["package"]["version"] = value(version.as_ref());
fs::write(path.as_ref(), doc.to_string())?;
Ok(())
}
pub fn bump_version(path: impl AsRef<Path>, r#type: SemVer) -> Result<Version, Error> {
let mut version = get_version(path.as_ref())?;
match r#type {
SemVer::Major => version.increment_major(),
SemVer::Minor => version.increment_minor(),
SemVer::Patch => version.increment_patch(),
}
set_version(path, &version.to_string())?;
Ok(version)
}