#![cfg_attr(not(feature = "std"), no_std)]
#![deny(unsafe_code, missing_docs)]
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "std")]
extern crate std as core;
use core::{error::Error as ErrorTrait, fmt};
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct Info<'a> {
pub specific: SpecificInfo<'a>,
pub source: Source,
}
impl<'a> Info<'a> {
#[inline]
#[must_use]
#[doc(alias = "revision")]
pub const fn commit(&self) -> &str {
self.specific.commit()
}
#[inline]
#[must_use]
pub const fn tags(&self) -> Option<&[&str]> {
self.specific.tags()
}
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum SpecificInfo<'a> {
Git {
commit_hash: &'a str,
extra: Option<&'a git::ExtraData<'a>>,
},
Mercurial {
global_revision: &'a str,
extra: Option<&'a mercurial::ExtraData<'a>>,
},
}
impl<'a> SpecificInfo<'a> {
#[inline]
#[must_use]
#[doc(alias = "revision")]
pub const fn commit(&self) -> &str {
match *self {
Self::Git { commit_hash, .. } => commit_hash,
Self::Mercurial {
global_revision, ..
} => global_revision,
}
}
#[inline]
#[must_use]
pub const fn tags(&self) -> Option<&[&str]> {
match *self {
Self::Git { extra, .. } => match extra {
Some(extra) => Some(extra.tags),
None => None,
},
Self::Mercurial { extra, .. } => match extra {
Some(extra) => Some(extra.tags),
None => None,
},
}
}
}
pub mod git {
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct ExtraData<'a> {
pub branch: &'a str,
pub tags: &'a [&'a str],
}
}
#[doc(inline)]
#[deprecated]
pub use git::ExtraData as GitExtraData;
pub mod mercurial {
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub struct ExtraData<'a> {
pub local_revision: &'a str,
pub branch: &'a str,
pub tags: &'a [&'a str],
pub bookmarks: &'a [&'a str],
}
}
#[doc(inline)]
#[deprecated]
pub use mercurial::ExtraData as MercurialExtraData;
#[non_exhaustive]
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum Source {
Repository,
CargoVcsInfoFile,
}
impl fmt::Debug for Source {
#[inline]
fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result {
let source = match *self {
Self::CargoVcsInfoFile => ".cargo_vcs_info.json",
Self::Repository => "Repository",
};
fmtr.write_str(source)
}
}
#[non_exhaustive]
pub enum Error {
NoVersionControl,
Redacted,
Other {
reason: &'static str,
},
}
impl fmt::Debug for Error {
#[inline]
fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Self::NoVersionControl => fmtr.debug_struct("NoVersionControl").finish(),
Self::Redacted => fmtr.debug_struct("Redacted").finish(),
Self::Other { ref reason } => {
fmtr.debug_struct("Other").field("reason", reason).finish()
}
}
}
}
impl fmt::Display for Error {
#[inline]
fn fmt(&self, fmtr: &mut fmt::Formatter<'_>) -> fmt::Result {
let message = match *self {
Self::NoVersionControl => "version control not found",
Self::Redacted => "version control information is redacted",
Self::Other { reason } => reason,
};
fmtr.write_str(message)
}
}
impl ErrorTrait for Error {}
#[macro_export]
macro_rules! get {
() => {
include!(concat!(
env!("OUT_DIR"),
"/version_control_info_get_generated.rs"
))
};
}
#[macro_export]
macro_rules! try_get {
() => {
include!(concat!(
env!("OUT_DIR"),
"/version_control_info_try_get_generated.rs"
))
};
}