core_semver/
lib.rs

1#![warn(missing_docs)]
2
3//! [Semantic Versioning](https://semver.org/) is a guideline for how version numbers are assigned and incremented. This crate is based on [semver](https://docs.rs/semver) and has some extended functions, such as **bump version**.
4
5// #![warn(missing_docs)]
6use semver::{Prerelease, Version};
7
8/// Bump trait can be used to define bump version
9pub trait Bump {
10    /// bump major and return version string
11    fn bump_major(&mut self) -> String;
12
13    /// bump minor and return version string
14    fn bump_minor(&mut self) -> String;
15
16    /// bump patch and return version string
17    fn bump_patch(&mut self) -> String;
18
19    /// bump pre and return version string
20    fn bump_pre(&mut self, preid: Option<&str>) -> String;
21}
22impl Bump for Version {
23    /// ```
24    /// use crate::core_semver::{parse,Bump};
25    ///
26    /// let mut version = core_semver::parse("1.2.3-beta.4");
27    /// assert_eq!(version.bump_major(), "2.0.0");
28    /// ```
29    fn bump_major(&mut self) -> String {
30        self.major += 1;
31        self.minor = 0;
32        self.patch = 0;
33        self.pre = Prerelease::EMPTY;
34        self.to_string()
35    }
36
37    /// ```
38    /// use crate::core_semver::{parse,Bump};
39    ///
40    /// let mut version = parse("1.2.3-beta.4");
41    /// assert_eq!(version.bump_minor(), "1.3.0");
42    /// ```
43    fn bump_minor(&mut self) -> String {
44        self.minor += 1;
45        self.patch = 0;
46        self.pre = Prerelease::EMPTY;
47        self.to_string()
48    }
49
50    /// ```
51    /// use crate::core_semver::{parse,Bump};
52    ///
53    /// let mut version = parse("1.2.3-beta.4");
54    /// assert_eq!(version.bump_patch(), "1.2.4");
55    /// ```
56    fn bump_patch(&mut self) -> String {
57        self.patch += 1;
58        self.pre = Prerelease::EMPTY;
59        self.to_string()
60    }
61
62    /// ```
63    /// use crate::core_semver::{parse,Bump};
64    ///
65    /// // default preid: beta
66    /// let mut version = parse("1.2.3");
67    /// assert_eq!(version.bump_pre(None), "1.3.3-beta.1");
68    ///
69    /// // default pre value: 1
70    /// version = parse("1.2.3-rc");
71    /// assert_eq!(version.bump_pre(None), "1.2.3-rc.1");
72    ///
73    /// version = parse("1.2.3-beta.4");
74    /// assert_eq!(version.bump_pre(None), "1.2.3-beta.5");
75    /// assert_eq!(version.bump_pre(Some("rc")), "1.2.3-rc.1");
76    /// ```
77    fn bump_pre(&mut self, preid: Option<&str>) -> String {
78        let mut has_preid = false;
79        let current_preid;
80        match preid {
81            Some(value) => {
82                if value.trim().len() == 0 {
83                    current_preid = "beta";
84                } else {
85                    current_preid = value.trim();
86                    has_preid = true;
87                }
88            }
89            None => {
90                current_preid = "beta";
91            }
92        }
93
94        if self.pre.is_empty() {
95            self.minor += 1;
96            self.pre = Prerelease::new(format!("{}.{}", current_preid, "1").as_str()).unwrap();
97            return self.to_string();
98        }
99
100        let mut pre_arr = self.pre.as_str().split(".").collect::<Vec<&str>>();
101        if pre_arr.len() == 0 {
102            pre_arr.push(&current_preid);
103            pre_arr.push("1");
104            self.pre = Prerelease::new(pre_arr.join(".").as_str()).unwrap();
105            return self.to_string();
106        }
107
108        let pre_value = pre_arr.pop().unwrap();
109        #[allow(unused_assignments)]
110        let mut next_value = pre_value.to_string();
111
112        match pre_value.parse::<u32>() {
113            Ok(value) => {
114                if has_preid {
115                    if current_preid == pre_arr.join(".") {
116                        next_value = (value + 1).to_string();
117                        pre_arr.push(next_value.as_str());
118                    } else {
119                        pre_arr.clear();
120                        pre_arr.push(&current_preid);
121                        pre_arr.push("1");
122                    }
123                } else {
124                    if pre_arr.len() == 0 {
125                        pre_arr.push(&current_preid);
126                    }
127
128                    next_value = (value + 1).to_string();
129                    pre_arr.push(next_value.as_str());
130                }
131            }
132            Err(_) => {
133                if has_preid {
134                    pre_arr.clear();
135                    pre_arr.push(&current_preid);
136                } else {
137                    pre_arr.push(pre_value);
138                }
139
140                pre_arr.push("1");
141            }
142        }
143
144        self.pre = Prerelease::new(pre_arr.join(".").as_str()).unwrap();
145
146        self.to_string()
147    }
148}
149
150/// parse version string based on [semver](https://docs.rs/semver)
151///
152/// ```
153/// use core_semver::parse;
154///
155/// let version = parse("1.2.3-beta.4");
156/// assert_eq!(version.major, 1);
157/// assert_eq!(version.minor, 2);
158/// assert_eq!(version.patch, 3);
159/// assert_eq!(version.pre.as_str(), "beta.4");
160/// assert_eq!(version.to_string(), "1.2.3-beta.4")
161/// ```
162pub fn parse(str: &str) -> Version {
163    Version::parse(str).unwrap()
164}