1 use crate::raw;
2 use libc::c_int;
3 use std::fmt;
4 
5 /// Version information about libgit2 and the capabilities it supports.
6 pub struct Version {
7     major: c_int,
8     minor: c_int,
9     rev: c_int,
10     features: c_int,
11 }
12 
13 macro_rules! flag_test {
14     ($features:expr, $flag:expr) => {
15         ($features as u32 & $flag as u32) != 0
16     };
17 }
18 
19 impl Version {
20     /// Returns a [`Version`] which provides information about libgit2.
get() -> Version21     pub fn get() -> Version {
22         let mut v = Version {
23             major: 0,
24             minor: 0,
25             rev: 0,
26             features: 0,
27         };
28         unsafe {
29             raw::git_libgit2_version(&mut v.major, &mut v.minor, &mut v.rev);
30             v.features = raw::git_libgit2_features();
31         }
32         v
33     }
34 
35     /// Returns the version of libgit2.
36     ///
37     /// The return value is a tuple of `(major, minor, rev)`
libgit2_version(&self) -> (u32, u32, u32)38     pub fn libgit2_version(&self) -> (u32, u32, u32) {
39         (self.major as u32, self.minor as u32, self.rev as u32)
40     }
41 
42     /// Returns the version of the libgit2-sys crate.
crate_version(&self) -> &'static str43     pub fn crate_version(&self) -> &'static str {
44         env!("CARGO_PKG_VERSION")
45     }
46 
47     /// Returns true if this was built with the vendored version of libgit2.
vendored(&self) -> bool48     pub fn vendored(&self) -> bool {
49         raw::vendored()
50     }
51 
52     /// Returns true if libgit2 was built thread-aware and can be safely used
53     /// from multiple threads.
threads(&self) -> bool54     pub fn threads(&self) -> bool {
55         flag_test!(self.features, raw::GIT_FEATURE_THREADS)
56     }
57 
58     /// Returns true if libgit2 was built with and linked against a TLS implementation.
59     ///
60     /// Custom TLS streams may still be added by the user to support HTTPS
61     /// regardless of this.
https(&self) -> bool62     pub fn https(&self) -> bool {
63         flag_test!(self.features, raw::GIT_FEATURE_HTTPS)
64     }
65 
66     /// Returns true if libgit2 was built with and linked against libssh2.
67     ///
68     /// A custom transport may still be added by the user to support libssh2
69     /// regardless of this.
ssh(&self) -> bool70     pub fn ssh(&self) -> bool {
71         flag_test!(self.features, raw::GIT_FEATURE_SSH)
72     }
73 
74     /// Returns true if libgit2 was built with support for sub-second
75     /// resolution in file modification times.
nsec(&self) -> bool76     pub fn nsec(&self) -> bool {
77         flag_test!(self.features, raw::GIT_FEATURE_NSEC)
78     }
79 }
80 
81 impl fmt::Debug for Version {
fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error>82     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
83         let mut f = f.debug_struct("Version");
84         f.field("major", &self.major)
85             .field("minor", &self.minor)
86             .field("rev", &self.rev)
87             .field("crate_version", &self.crate_version())
88             .field("vendored", &self.vendored())
89             .field("threads", &self.threads())
90             .field("https", &self.https())
91             .field("ssh", &self.ssh())
92             .field("nsec", &self.nsec());
93         f.finish()
94     }
95 }
96