use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Activation {
Height(u64),
Ranges(Vec<(u64, u64)>),
}
impl Activation {
pub fn is_active_at(&self, height: u64) -> bool {
match self {
Activation::Height(activation_height) => {
height >= *activation_height
}
Activation::Ranges(ranges) => ranges
.iter()
.any(|(start, end)| height >= *start && height <= *end),
}
}
pub fn unwrap_height(&self) -> u64 {
match self {
Activation::Height(height) => *height,
Activation::Ranges(_) => {
panic!("Called unwrap_height on Activation::Ranges")
}
}
}
pub fn unwrap_ranges(&self) -> &[(u64, u64)] {
match self {
Activation::Height(_) => {
panic!("Called unwrap_height on Activation::Height")
}
Activation::Ranges(ranges) => &ranges[..],
}
}
}
impl From<u64> for Activation {
fn from(height: u64) -> Self {
Activation::Height(height)
}
}
impl From<Vec<(u64, u64)>> for Activation {
fn from(ranges: Vec<(u64, u64)>) -> Self {
Activation::Ranges(ranges)
}
}
impl Display for Activation {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Activation::Height(height) => {
write!(f, "Height({})", height)
}
Activation::Ranges(ranges) => {
let ranges_str = ranges
.iter()
.map(|(start, end)| format!("({start},{end})"))
.collect::<Vec<_>>()
.join(", ");
write!(f, "Ranges([{ranges_str}])")
}
}
}
}