macro_rules! feature_check {
($feature:literal, $name:ident, $doc:expr) => {
#[cfg(feature = $feature)]
#[doc = $doc]
pub fn $name() -> bool {
true
}
#[cfg(not(feature = $feature))]
#[doc = $doc]
pub fn $name() -> bool {
false
}
};
}
feature_check!("memory", l1_available, "Check if L1 cache is available");
feature_check!("redis", l2_available, "Check if L2 cache is available");
feature_check!("metrics", metrics_available, "Check if metrics are available");
feature_check!(
"batch-write",
batch_write_available,
"Check if batch write is available"
);
feature_check!(
"serialization",
serialization_available,
"Check if serialization is available"
);
feature_check!(
"compression",
compression_available,
"Check if compression is available"
);
feature_check!("cli", cli_available, "Check if CLI is available");
#[derive(Debug, Clone)]
pub struct FeatureSet {
pub(crate) l1_available: bool,
pub(crate) l2_available: bool,
pub(crate) metrics_available: bool,
pub(crate) cli_available: bool,
}
impl FeatureSet {
pub fn current() -> Self {
Self {
l1_available: l1_available(),
l2_available: l2_available(),
metrics_available: metrics_available(),
cli_available: cli_available(),
}
}
pub fn tier_name(&self) -> &'static str {
if self.cli_available && self.metrics_available {
"full"
} else if self.l2_available && self.metrics_available {
"core"
} else if self.l1_available {
"minimal"
} else {
"core"
}
}
}
impl Default for FeatureSet {
fn default() -> Self {
Self::current()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_feature_set_current() {
let fs = FeatureSet::current();
assert!(fs.l1_available);
assert!(fs.l2_available);
assert!(fs.metrics_available);
assert!(fs.cli_available);
}
#[test]
fn test_feature_set_default() {
let fs = FeatureSet::default();
let current = FeatureSet::current();
assert_eq!(fs.l1_available, current.l1_available);
assert_eq!(fs.l2_available, current.l2_available);
assert_eq!(fs.metrics_available, current.metrics_available);
assert_eq!(fs.cli_available, current.cli_available);
}
#[test]
fn test_feature_set_tier_name_full() {
let fs = FeatureSet {
l1_available: true,
l2_available: true,
metrics_available: true,
cli_available: true,
};
assert_eq!(fs.tier_name(), "full");
}
#[test]
fn test_feature_set_tier_name_core_with_l2() {
let fs = FeatureSet {
l1_available: true,
l2_available: true,
metrics_available: true,
cli_available: false,
};
assert_eq!(fs.tier_name(), "core");
}
#[test]
fn test_feature_set_tier_name_minimal() {
let fs = FeatureSet {
l1_available: true,
l2_available: false,
metrics_available: false,
cli_available: false,
};
assert_eq!(fs.tier_name(), "minimal");
}
#[test]
fn test_feature_set_tier_name_core_fallback() {
let fs = FeatureSet {
l1_available: false,
l2_available: false,
metrics_available: false,
cli_available: false,
};
assert_eq!(fs.tier_name(), "core");
}
#[test]
fn test_l1_available() {
assert!(l1_available());
}
#[test]
fn test_l2_available() {
assert!(l2_available());
}
#[test]
fn test_metrics_available() {
assert!(metrics_available());
}
#[test]
fn test_cli_available() {
assert!(cli_available());
}
#[test]
fn test_batch_write_available() {
assert!(batch_write_available());
}
#[test]
fn test_serialization_available() {
assert!(serialization_available());
}
#[test]
fn test_compression_available() {
let _ = compression_available();
}
}