#![forbid(unsafe_code)]
#![doc = include_str!("../README.md")]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub enum LayerRole {
Base,
Raised,
Sticky,
Dropdown,
Popover,
Tooltip,
Modal,
Toast,
Overlay,
}
impl LayerRole {
pub fn index(self) -> LayerIndex {
match self {
Self::Base => LayerIndex::new(0),
Self::Raised => LayerIndex::new(100),
Self::Sticky => LayerIndex::new(200),
Self::Dropdown => LayerIndex::new(1_000),
Self::Popover => LayerIndex::new(1_100),
Self::Tooltip => LayerIndex::new(1_200),
Self::Modal => LayerIndex::new(1_300),
Self::Toast => LayerIndex::new(1_400),
Self::Overlay => LayerIndex::new(1_500),
}
}
pub fn sits_above(self, other: Self) -> bool {
self.index() > other.index()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct LayerIndex(i32);
impl LayerIndex {
pub fn new(value: i32) -> Self {
Self(value)
}
pub fn value(self) -> i32 {
self.0
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct LayerStack {
layers: Vec<LayerRole>,
}
impl LayerStack {
pub fn new(layers: Vec<LayerRole>) -> Self {
Self { layers }
}
pub fn layers(&self) -> &[LayerRole] {
&self.layers
}
pub fn top(&self) -> Option<LayerRole> {
self.layers
.iter()
.copied()
.max_by_key(|layer| layer.index())
}
pub fn is_above(&self, layer: LayerRole, other: LayerRole) -> bool {
self.layers.contains(&layer) && self.layers.contains(&other) && layer.sits_above(other)
}
}
#[cfg(test)]
mod tests {
use super::{LayerIndex, LayerRole, LayerStack};
#[test]
fn compares_layer_roles() {
assert!(LayerRole::Modal.sits_above(LayerRole::Popover));
assert!(!LayerRole::Base.sits_above(LayerRole::Raised));
assert_eq!(LayerRole::Tooltip.index().value(), 1_200);
assert!(LayerIndex::new(20) > LayerIndex::new(10));
}
#[test]
fn finds_top_layer_in_stack() {
let stack = LayerStack::new(vec![LayerRole::Base, LayerRole::Popover, LayerRole::Modal]);
assert_eq!(stack.top(), Some(LayerRole::Modal));
assert!(stack.is_above(LayerRole::Modal, LayerRole::Popover));
assert!(!stack.is_above(LayerRole::Toast, LayerRole::Modal));
}
}