pub fn encode_btc_price(price_usd: Option<f64>) -> u8 {
let price_usd = match price_usd {
Some(p) => p,
None => return 0,
};
if price_usd < 1.0 {
return 0;
}
if price_usd <= 100.0 {
return 1 + ((price_usd / 20.0) as u8).min(4);
}
if price_usd <= 1000.0 {
return 6 + (((price_usd - 100.0) / 180.0) as u8).min(4);
}
if price_usd <= 10000.0 {
return 11 + (((price_usd - 1000.0) / 600.0) as u8).min(14);
}
if price_usd <= 50000.0 {
return 26 + (((price_usd - 10000.0) / 2666.0) as u8).min(14);
}
if price_usd <= 150000.0 {
return 41 + (((price_usd - 50000.0) / 6666.0) as u8).min(14);
}
if price_usd <= 500000.0 {
return 56 + (((price_usd - 150000.0) / 50000.0) as u8).min(6);
}
63
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_none_returns_zero() {
assert_eq!(encode_btc_price(None), 0);
}
#[test]
fn test_below_one_dollar_returns_zero() {
assert_eq!(encode_btc_price(Some(0.5)), 0);
}
#[test]
fn test_100k_usd_in_high_range() {
let tier = encode_btc_price(Some(100_000.0));
assert!(tier >= 41, "100k should be in the 41–55 range, got {tier}");
}
#[test]
fn test_encoding_is_monotone() {
let prices = [
1.0, 100.0, 1_000.0, 10_000.0, 50_000.0, 100_000.0, 500_000.0,
];
let tiers: Vec<u8> = prices.iter().map(|&p| encode_btc_price(Some(p))).collect();
for i in 1..tiers.len() {
assert!(
tiers[i] >= tiers[i - 1],
"tier[{}]={} should be >= tier[{}]={} (prices: {} vs {})",
i,
tiers[i],
i - 1,
tiers[i - 1],
prices[i],
prices[i - 1]
);
}
}
#[test]
fn test_max_tier_at_very_high_price() {
assert_eq!(encode_btc_price(Some(1_000_000.0)), 63);
}
}