manabrew_engine/
game_log_formatter.rs1use crate::game_log_entry::GameLogEntry;
2use crate::game_log_entry_type::GameLogEntryType;
3
4pub trait GameLogFormatter: Send + Sync {
7 fn format(&self, entry: &GameLogEntry) -> String;
8}
9
10pub struct ConsoleGameLogFormatter;
12
13impl ConsoleGameLogFormatter {
14 const ANSI_RESET: &'static str = "\x1b[0m";
15 const ANSI_WHITE: &'static str = "\x1b[37m";
16 const ANSI_GREY: &'static str = "\x1b[90m";
17 const ANSI_LIGHT_GREY: &'static str = "\x1b[37m";
18 const ANSI_GREEN: &'static str = "\x1b[32m";
19 const ANSI_YELLOW: &'static str = "\x1b[33m";
20 const ANSI_BLUE: &'static str = "\x1b[34m";
21
22 fn indent_prefix(level: usize) -> String {
23 let mut out = String::new();
24 for ancestor_depth in 0..level {
25 out.push_str(Self::color_for_depth(ancestor_depth));
26 out.push('|');
27 out.push_str(Self::ANSI_RESET);
28 out.push_str(" ");
29 }
30 out
31 }
32
33 fn label(entry_type: GameLogEntryType) -> &'static str {
34 match entry_type {
35 GameLogEntryType::TurnBegin => "TURN",
36 GameLogEntryType::TurnSkip => "TURN",
37 GameLogEntryType::PhaseBegin => "PHASE",
38 GameLogEntryType::PriorityWaiting => "WAIT",
39 GameLogEntryType::PriorityResponse => "RESP",
40 GameLogEntryType::PriorityPass => "PASS",
41 GameLogEntryType::StackPush => "STACK",
42 GameLogEntryType::StackResolve => "STACK",
43 GameLogEntryType::Mulligan => "MULL",
44 GameLogEntryType::Info => "INFO",
45 }
46 }
47
48 fn color_for_depth(depth: usize) -> &'static str {
49 match depth % 4 {
50 0 => Self::ANSI_WHITE,
51 1 => Self::ANSI_YELLOW,
52 2 => Self::ANSI_BLUE,
53 _ => Self::ANSI_GREY,
54 }
55 }
56
57 fn color_for_entry(entry_type: GameLogEntryType) -> &'static str {
58 match entry_type {
59 GameLogEntryType::TurnBegin | GameLogEntryType::TurnSkip => Self::ANSI_WHITE,
60 GameLogEntryType::PhaseBegin => Self::ANSI_YELLOW,
61 GameLogEntryType::PriorityPass => Self::ANSI_GREY,
62 GameLogEntryType::PriorityResponse => Self::ANSI_GREEN,
63 GameLogEntryType::StackPush | GameLogEntryType::StackResolve => Self::ANSI_BLUE,
64 GameLogEntryType::Info => Self::ANSI_LIGHT_GREY,
65 _ => Self::ANSI_GREEN,
66 }
67 }
68}
69
70impl GameLogFormatter for ConsoleGameLogFormatter {
71 fn format(&self, entry: &GameLogEntry) -> String {
72 let indent = Self::indent_prefix(entry.indent);
73 let line_color = Self::color_for_entry(entry.entry_type);
74 let payload = format!("-- [{}] {}", Self::label(entry.entry_type), entry.message);
75 format!("{indent}{line_color}{payload}{}", Self::ANSI_RESET)
76 }
77}