use ratatui::style::Color;
use super::icon::Icon;
use crate::domain::session::{ReviewRequestState, Status};
pub mod palette {
use ratatui::style::Color;
pub const ACCENT: Color = Color::Cyan;
pub const ACCENT_SOFT: Color = Color::LightCyan;
pub const BORDER: Color = Color::DarkGray;
pub const DANGER: Color = Color::Red;
pub const DANGER_SOFT: Color = Color::LightRed;
pub const INFO: Color = Color::LightBlue;
pub const QUESTION: Color = Color::LightMagenta;
pub const SURFACE: Color = Color::DarkGray;
pub const SURFACE_DANGER: Color = Color::Rgb(48, 24, 24);
pub const SURFACE_ELEVATED: Color = Color::Gray;
pub const SURFACE_SUCCESS: Color = Color::Rgb(18, 44, 26);
pub const SURFACE_OVERLAY: Color = Color::Black;
pub const TEXT: Color = Color::White;
pub const TEXT_MUTED: Color = Color::Gray;
pub const TEXT_SUBTLE: Color = Color::DarkGray;
pub const SUCCESS: Color = Color::Green;
pub const SUCCESS_SOFT: Color = Color::LightGreen;
pub const WARNING: Color = Color::Yellow;
pub const WARNING_SOFT: Color = Color::LightYellow;
}
pub fn status_color(status: Status) -> Color {
match status {
Status::New => palette::TEXT_MUTED,
Status::InProgress => palette::WARNING,
Status::Review | Status::AgentReview => palette::INFO,
Status::Question => palette::QUESTION,
Status::Queued => palette::ACCENT_SOFT,
Status::Rebasing | Status::Merging => palette::ACCENT,
Status::Done => palette::SUCCESS,
Status::Canceled => palette::DANGER,
}
}
pub fn status_icon(status: Status) -> Icon {
match status {
Status::New | Status::Review | Status::Question | Status::Queued => Icon::Pending,
Status::InProgress | Status::AgentReview | Status::Rebasing | Status::Merging => {
Icon::current_spinner()
}
Status::Done => Icon::Check,
Status::Canceled => Icon::Cross,
}
}
pub fn forge_indicator_color(state: Option<ReviewRequestState>) -> Color {
match state {
Some(ReviewRequestState::Open) => palette::WARNING,
Some(ReviewRequestState::Merged) => palette::SUCCESS,
Some(ReviewRequestState::Closed) => palette::DANGER,
None => palette::ACCENT_SOFT,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn status_color_returns_muted_text_for_new() {
let color = status_color(Status::New);
assert_eq!(color, palette::TEXT_MUTED);
}
#[test]
fn status_color_returns_success_for_done() {
let color = status_color(Status::Done);
assert_eq!(color, palette::SUCCESS);
}
#[test]
fn status_color_returns_danger_for_canceled() {
let color = status_color(Status::Canceled);
assert_eq!(color, palette::DANGER);
}
#[test]
fn status_color_returns_warning_for_in_progress() {
let color = status_color(Status::InProgress);
assert_eq!(color, palette::WARNING);
}
#[test]
fn status_color_returns_info_for_review() {
let color = status_color(Status::Review);
assert_eq!(color, palette::INFO);
}
#[test]
fn status_color_returns_accent_for_merging() {
let color = status_color(Status::Merging);
assert_eq!(color, palette::ACCENT);
}
#[test]
fn status_icon_returns_check_for_done() {
let icon = status_icon(Status::Done);
assert!(matches!(icon, Icon::Check));
}
#[test]
fn status_icon_returns_cross_for_canceled() {
let icon = status_icon(Status::Canceled);
assert!(matches!(icon, Icon::Cross));
}
#[test]
fn status_icon_returns_pending_for_new() {
let icon = status_icon(Status::New);
assert!(matches!(icon, Icon::Pending));
}
#[test]
fn forge_indicator_color_returns_warning_for_open() {
let color = forge_indicator_color(Some(ReviewRequestState::Open));
assert_eq!(color, palette::WARNING);
}
#[test]
fn forge_indicator_color_returns_success_for_merged() {
let color = forge_indicator_color(Some(ReviewRequestState::Merged));
assert_eq!(color, palette::SUCCESS);
}
#[test]
fn forge_indicator_color_returns_danger_for_closed() {
let color = forge_indicator_color(Some(ReviewRequestState::Closed));
assert_eq!(color, palette::DANGER);
}
#[test]
fn forge_indicator_color_returns_accent_soft_for_published_only() {
let color = forge_indicator_color(None);
assert_eq!(color, palette::ACCENT_SOFT);
}
}