use std::time::{Duration, SystemTime};
use serde::{Deserialize, Serialize};
use super::error::LicenseErrorCode;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum LicenseState {
Loading,
MissingKey,
Active,
InvalidKey,
Expired,
VersionNotAllowed,
MachineLimitReached,
OfflineExpired,
ClockTampered,
}
impl LicenseState {
pub fn as_str(self) -> &'static str {
match self {
Self::Loading => "LOADING",
Self::MissingKey => "MISSING_KEY",
Self::Active => "ACTIVE",
Self::InvalidKey => "INVALID_KEY",
Self::Expired => "EXPIRED",
Self::VersionNotAllowed => "VERSION_NOT_ALLOWED",
Self::MachineLimitReached => "MACHINE_LIMIT_REACHED",
Self::OfflineExpired => "OFFLINE_EXPIRED",
Self::ClockTampered => "CLOCK_TAMPERED",
}
}
}
impl std::fmt::Display for LicenseState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum OfflineState {
Online,
Offline {
valid_until: Option<SystemTime>,
remaining: Duration,
},
}
pub(crate) fn locked_state(code: LicenseErrorCode) -> Option<LicenseState> {
match code {
LicenseErrorCode::NotFound => Some(LicenseState::InvalidKey),
LicenseErrorCode::LicenseExpired => Some(LicenseState::Expired),
LicenseErrorCode::VersionNotAllowed => Some(LicenseState::VersionNotAllowed),
LicenseErrorCode::MachineLimitReached => Some(LicenseState::MachineLimitReached),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn serializes_states_like_electron() {
for state in [
LicenseState::Loading,
LicenseState::MissingKey,
LicenseState::Active,
LicenseState::InvalidKey,
LicenseState::Expired,
LicenseState::VersionNotAllowed,
LicenseState::MachineLimitReached,
LicenseState::OfflineExpired,
LicenseState::ClockTampered,
] {
assert_eq!(
serde_json::to_string(&state).unwrap(),
format!("\"{state}\"")
);
}
}
#[test]
fn locked_states() {
assert_eq!(
locked_state(LicenseErrorCode::NotFound),
Some(LicenseState::InvalidKey)
);
assert_eq!(
locked_state(LicenseErrorCode::LicenseExpired),
Some(LicenseState::Expired)
);
assert_eq!(
locked_state(LicenseErrorCode::VersionNotAllowed),
Some(LicenseState::VersionNotAllowed)
);
assert_eq!(
locked_state(LicenseErrorCode::MachineLimitReached),
Some(LicenseState::MachineLimitReached)
);
assert_eq!(locked_state(LicenseErrorCode::NetworkError), None);
}
}