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
use semver::Version as SemverVersion;
use std::str::FromStr;
use target_lexicon::Triple;
use time::{format_description::well_known::Iso8601, Date};
use super::{ParsingError, Result};
/// Parsed output of running "cargo --version --verbose".
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Version {
/// Version of this release of cargo, E.g. "1.62.0".
pub release: SemverVersion,
/// The sha1 hash of the latest commit when this version of cargo was published.
///
/// May be missing if not built from git.
pub commit_hash: Option<String>,
/// The date of the latest commit when this version of cargo was published.
///
/// May be missing if not built from git.
pub commit_date: Option<Date>,
/// The host target triple, E.g. "x86_64-unknown-linux-gnu".
pub host: Triple,
/// The version of the bundled libgit2.
pub libgit2: String,
/// The version of the bundled libcurl.
pub libcurl: String,
/// The current operating system, E.g. "Arch Linux Rolling Release \[64-bit\]".
pub os: String,
}
impl FromStr for Version {
type Err = ParsingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut lines = s.lines();
// Search for a line starting with "release: ", if not found returns an error otherwise it parses it as a semver::Version.
let release = lines
.find_map(|line| line.strip_prefix("release: "))
.ok_or(ParsingError::Version("release"))?
.parse()?;
// Search for a line starting with "commit-hash: " and returns it still wrapped in an option.
let commit_hash = lines
.find_map(|line| line.strip_prefix("commit-hash: "))
.map(|line| line.to_string());
// Search for a line starting with "commit-date: ", parses it as a time::Date and returns it still wrapped in an option.
let commit_date = lines
.find_map(|line| line.strip_prefix("commit-date: "))
.map(|line| line.to_string())
.map(|commit_date| Date::parse(&commit_date, &Iso8601::DEFAULT).unwrap());
// Search for a line starting with "host: ", if not found returns an error otherwise it parses it as a target_lexicon::Triple.
let host = lines
.find_map(|line| line.strip_prefix("host: "))
.ok_or(ParsingError::Version("host"))?
.parse()?;
// Search for a line starting with "libgit2: ", if not found returns an error otherwise returns it as a String.
let libgit2 = lines
.find_map(|line| line.strip_prefix("libgit2: "))
.map(|line| line.to_string())
.ok_or(ParsingError::Version("libgit2"))?;
// Search for a line starting with "libcurl: ", if not found returns an error otherwise returns it as a String.
let libcurl = lines
.find_map(|line| line.strip_prefix("libcurl: "))
.map(|line| line.to_string())
.ok_or(ParsingError::Version("libcurl"))?;
// Search for a line starting with "os: ", if not found returns an error otherwise returns it as a String.
let os = lines
.find_map(|line| line.strip_prefix("os: "))
.map(|line| line.to_string())
.ok_or(ParsingError::Version("os"))?;
Ok(Version {
release,
commit_hash,
commit_date,
host,
libgit2,
libcurl,
os,
})
}
}