use crate::error::{Error, Result};
use crate::host::{OS, Os};
pub const OPENED: bool = cfg!(any(test, pitboard_unreleased_windows));
const VERSION: &str = env!("CARGO_PKG_VERSION");
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Decision {
Runs,
NotReleased,
}
pub fn decision(os: Os, version: &str, opened: bool) -> Decision {
let major = version
.split('.')
.next()
.and_then(|major| major.parse::<u64>().ok())
.unwrap_or(0);
match os {
Os::MacOs | Os::Linux => Decision::Runs,
Os::Windows if major >= 1 || opened => Decision::Runs,
Os::Windows => Decision::NotReleased,
}
}
pub fn check() -> Result<()> {
match decision(OS, VERSION, OPENED) {
Decision::Runs => Ok(()),
Decision::NotReleased => Err(Error::WindowsNotReleased),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn only_a_windows_build_of_a_release_before_1_0_refuses() {
for version in ["0.7.0", "0.8.0", "0.99.1", "not a version", ""] {
assert_eq!(
decision(Os::Windows, version, false),
Decision::NotReleased,
"{version}"
);
assert_eq!(
decision(Os::Windows, version, true),
Decision::Runs,
"{version}"
);
}
for version in ["1.0.0-beta.1", "1.0.0-beta.12", "1.0.0", "1.4.2", "2.0.0"] {
for opened in [false, true] {
assert_eq!(
decision(Os::Windows, version, opened),
Decision::Runs,
"{version}, opened {opened}"
);
}
}
for os in [Os::MacOs, Os::Linux] {
for version in ["0.7.0", "0.8.0", "1.0.0-beta.1", "1.0.0", "not a version"] {
for opened in [false, true] {
assert_eq!(
decision(os, version, opened),
Decision::Runs,
"{os:?}, {version}, opened {opened}"
);
}
}
}
}
#[test]
fn this_build_answers_for_its_own_system_and_version() {
const { assert!(OPENED) };
assert_eq!(
check().is_ok(),
decision(OS, VERSION, OPENED) == Decision::Runs
);
assert!(check().is_ok());
let refused = Error::WindowsNotReleased;
assert_eq!(refused.code(), "windows_not_released");
assert_eq!(
refused.to_string(),
"Pitboard for Windows is not released yet. This build changes nothing."
);
assert_eq!(refused.exit_code(), 1);
}
}