simple_version/lib.rs
1#![no_std]
2
3
4#[cfg(test)]
5mod tests;
6
7
8/// A struct that represents a version consisting of major, minor, patch, and an optional build number.
9///
10/// The generic parameter `T` specifies the numerical type to use for each version component.
11///
12/// ***
13/// # Examples
14///
15/// Creating a version without a build number:
16///
17/// ```rust
18/// use simple_version::Version;
19///
20/// let version: Version<u32> = Version::new(1, 2, 3);
21/// ```
22///
23/// ***
24///
25/// Creating a version with a build number:
26///
27/// ```rust
28/// use simple_version::Version;
29///
30/// let version: Version<u32> = Version::new(1, 2, 3).build(4);
31/// ```
32#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
33pub struct Version<T: Ord> {
34 /// The major version component.
35 ///
36 /// ***
37 /// # Examples
38 ///
39 /// ```rust
40 /// use simple_version::Version;
41 ///
42 /// let mut version = Version::<u32>::new(1, 2, 3);
43 ///
44 /// // read major version
45 /// println!("{}", version.major);
46 ///
47 /// // set major version
48 /// version.major = 4;
49 /// ```
50 pub major: T,
51
52 /// The minor version component.
53 ///
54 /// ***
55 /// # Examples
56 ///
57 /// ```rust
58 /// use simple_version::Version;
59 ///
60 /// let mut version = Version::<u32>::new(1, 2, 3);
61 ///
62 /// // read minor version
63 /// println!("{}", version.minor);
64 ///
65 /// // set minor version
66 /// version.minor = 4;
67 /// ```
68 pub minor: T,
69
70 /// The patch version component.
71 ///
72 /// ***
73 /// # Examples
74 ///
75 /// ```rust
76 /// use simple_version::Version;
77 ///
78 /// let mut version = Version::<u32>::new(1, 2, 3);
79 ///
80 /// // read patch version
81 /// println!("{}", version.patch);
82 ///
83 /// // set patch version
84 /// version.patch = 4;
85 /// ```
86 pub patch: T,
87
88 /// The optional build number.
89 ///
90 /// ***
91 /// # Examples
92 ///
93 /// ```rust
94 /// use simple_version::Version;
95 ///
96 /// // version with a build number
97 /// let mut version = Version::<u32>::new(1, 2, 3).build(4);
98 ///
99 /// // read build number
100 /// if let Some(build) = version.build {
101 /// println!("{}", build);
102 /// }
103 ///
104 /// // set build number
105 /// version.build = Some(5);
106 /// ```
107 pub build: Option<T>,
108}
109
110
111impl<T: Ord> Version<T> {
112 /// Creates a new `Version<T>` without a build number.
113 ///
114 /// ***
115 /// # Arguments
116 ///
117 /// - `major`: the major version component
118 /// - `minor`: the minor version component
119 /// - `patch`: the patch version component
120 ///
121 /// ***
122 /// # Examples
123 ///
124 /// ```rust
125 /// use simple_version::Version;
126 ///
127 /// let version: Version<u32> = Version::new(1, 2, 3);
128 /// ```
129 pub fn new(major: T, minor: T, patch: T) -> Version<T> {
130 Version { major, minor, patch, build: None }
131 }
132
133 /// Adds a build number to the existing version object and returns it.
134 ///
135 /// ***
136 /// # Arguments
137 ///
138 /// - `build`: the build number
139 ///
140 /// ***
141 /// # Examples
142 ///
143 /// ```rust
144 /// use simple_version::Version;
145 ///
146 /// let version: Version<u32> = Version::new(1, 2, 3).build(4);
147 /// ```
148 pub fn build(mut self, build: T) -> Version<T> {
149 self.build = Some(build);
150 self
151 }
152}
153
154
155impl<T: Ord + core::fmt::Display> core::fmt::Display for Version<T> {
156 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
157 if let Some(build) = &self.build {
158 write!(f, "{}.{}.{}+{}", self.major, self.minor, self.patch, build)
159 } else {
160 write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
161 }
162 }
163}
164
165
166/// Creates a new `Version<T>` from the `CARGO_PKG_VERSION` environment variable
167/// at compile time (i.e., from your crate's `Cargo.toml`).
168///
169/// ***
170/// # Examples
171///
172/// ```rust
173/// use simple_version::{Version, version_from_pkg};
174///
175/// let version: Version<u32> = version_from_pkg!(u32);
176/// // Now `version` might be e.g. 1.2.3 if your crate's version is "1.2.3"
177/// ```
178#[macro_export]
179macro_rules! version_from_pkg {
180 ($t:ty) => {{
181 let _major: $t = env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap();
182 let _minor: $t = env!("CARGO_PKG_VERSION_MINOR").parse().unwrap();
183 let _patch: $t = env!("CARGO_PKG_VERSION_PATCH").parse().unwrap();
184 $crate::Version::new(_major, _minor, _patch)
185 }};
186}