use ratatui::layout::Rect;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ZoneId(u32);
impl ZoneId {
#[must_use]
pub const fn new(id: u32) -> Self {
Self(id)
}
#[must_use]
pub const fn raw(self) -> u32 {
self.0
}
}
impl std::fmt::Display for ZoneId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "zone:{}", self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ZoneHint {
Tab,
Sidebar,
Control,
Overlay,
StatusBar,
}
#[derive(Debug, Clone)]
pub struct ZoneRequest {
pub name: String,
pub hint: ZoneHint,
pub label: String,
pub preferred_height: u16,
pub preferred_width: u16,
pub min_terminal_width: u16,
pub order: u8,
}
impl ZoneRequest {
#[must_use]
pub fn tab(name: impl Into<String>, label: impl Into<String>) -> Self {
Self {
name: name.into(),
hint: ZoneHint::Tab,
label: label.into(),
preferred_height: 0,
preferred_width: 0,
min_terminal_width: 0,
order: 128,
}
}
#[must_use]
pub fn sidebar(name: impl Into<String>, label: impl Into<String>) -> Self {
Self {
name: name.into(),
hint: ZoneHint::Sidebar,
label: label.into(),
preferred_height: 0,
preferred_width: 0,
min_terminal_width: 120,
order: 128,
}
}
#[must_use]
pub fn overlay(
name: impl Into<String>,
label: impl Into<String>,
width: u16,
height: u16,
) -> Self {
Self {
name: name.into(),
hint: ZoneHint::Overlay,
label: label.into(),
preferred_height: height,
preferred_width: width,
min_terminal_width: 0,
order: 0,
}
}
#[must_use]
pub fn with_order(mut self, order: u8) -> Self {
self.order = order;
self
}
#[must_use]
pub fn with_min_width(mut self, width: u16) -> Self {
self.min_terminal_width = width;
self
}
}
#[derive(Debug, Clone)]
pub struct ZoneSpec {
pub id: ZoneId,
pub name: String,
pub label: String,
pub hint: ZoneHint,
pub area: Rect,
pub visible: bool,
pub order: u8,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn zone_id_display() {
assert_eq!(ZoneId::new(42).to_string(), "zone:42");
}
#[test]
fn zone_id_equality() {
assert_eq!(ZoneId::new(1), ZoneId::new(1));
assert_ne!(ZoneId::new(1), ZoneId::new(2));
}
#[test]
fn zone_request_tab() {
let req = ZoneRequest::tab("bmad.sprint", "Sprint");
assert_eq!(req.hint, ZoneHint::Tab);
assert_eq!(req.name, "bmad.sprint");
assert_eq!(req.label, "Sprint");
}
#[test]
fn zone_request_sidebar() {
let req = ZoneRequest::sidebar("github.pr", "Pull Requests");
assert_eq!(req.hint, ZoneHint::Sidebar);
assert_eq!(req.min_terminal_width, 120);
}
#[test]
fn zone_request_overlay() {
let req = ZoneRequest::overlay("finder.search", "Search", 60, 20);
assert_eq!(req.hint, ZoneHint::Overlay);
assert_eq!(req.preferred_width, 60);
assert_eq!(req.preferred_height, 20);
}
#[test]
fn zone_request_builder() {
let req = ZoneRequest::tab("test.tab", "Test")
.with_order(10)
.with_min_width(140);
assert_eq!(req.order, 10);
assert_eq!(req.min_terminal_width, 140);
}
}