devalang_core/utils/
logger.rs

1#[cfg(feature = "cli")]
2use crossterm::style::{Attribute, Color, ResetColor, SetAttribute, SetForegroundColor};
3use std::fmt::Write;
4
5#[derive(Debug, Clone, PartialEq)]
6pub enum LogLevel {
7    Success,
8    Error,
9    Info,
10    Print,
11    Warning,
12    Watcher,
13    Debug,
14}
15
16#[derive(Debug, Clone)]
17pub struct Logger;
18
19impl Logger {
20    pub fn new() -> Self {
21        Logger
22    }
23
24    // --- log_message ---
25
26    #[cfg(feature = "cli")]
27    pub fn log_message(&self, level: LogLevel, message: &str) {
28        let formatted_status = self.format_status(level);
29        println!("🦊 {} {} {}", self.language_signature(), formatted_status, message);
30    }
31
32    #[cfg(not(feature = "cli"))]
33    pub fn log_message(&self, _level: LogLevel, _message: &str) {
34        // no-op for WASM
35    }
36
37    // --- log_message_with_trace ---
38
39    #[cfg(feature = "cli")]
40    pub fn log_message_with_trace(&self, level: LogLevel, message: &str, trace: Vec<&str>) {
41        let formatted_status = self.format_status(level);
42        println!("🦊 {} {} {}", self.language_signature(), formatted_status, message);
43        for t in trace {
44            println!("     ↳ {}", t);
45        }
46    }
47
48    #[cfg(not(feature = "cli"))]
49    pub fn log_message_with_trace(&self, _level: LogLevel, _message: &str, _trace: Vec<&str>) {
50        // no-op for WASM
51    }
52
53    // --- log_error_with_stacktrace ---
54
55    #[cfg(feature = "cli")]
56    pub fn log_error_with_stacktrace(&self, message: &str, stacktrace: &str) {
57        let formatted_status = self.format_status(LogLevel::Error);
58        println!("🦊 {} {} {}", self.language_signature(), formatted_status, message);
59        println!("     ↳ {}", stacktrace);
60    }
61
62    #[cfg(not(feature = "cli"))]
63    pub fn log_error_with_stacktrace(&self, _message: &str, _stacktrace: &str) {
64        // no-op for WASM
65    }
66
67    // --- language_signature ---
68
69    #[cfg(feature = "cli")]
70    fn language_signature(&self) -> String {
71        let mut s = String::new();
72
73        write!(&mut s, "{}", SetForegroundColor(Color::Grey)).unwrap();
74        s.push('[');
75
76        write!(&mut s, "{}", SetForegroundColor(Color::Rgb { r: 29, g: 211, b: 176 })).unwrap();
77        write!(&mut s, "{}", SetAttribute(Attribute::Bold)).unwrap();
78        s.push_str("Devalang");
79        write!(&mut s, "{}", SetAttribute(Attribute::Reset)).unwrap();
80
81        write!(&mut s, "{}", SetForegroundColor(Color::Grey)).unwrap();
82        s.push(']');
83        write!(&mut s, "{}", ResetColor).unwrap();
84
85        s
86    }
87
88    #[cfg(not(feature = "cli"))]
89    fn language_signature(&self) -> String {
90        "[Devalang]".to_string()
91    }
92
93    // --- format_status ---
94
95    #[cfg(feature = "cli")]
96    fn format_status(&self, level: LogLevel) -> String {
97        let mut s = String::new();
98
99        let color = match level {
100            LogLevel::Success => Color::Rgb { r: 76, g: 175, b: 80 },
101            LogLevel::Error => Color::Rgb { r: 244, g: 67, b: 54 },
102            LogLevel::Info => Color::Rgb { r: 33, g: 150, b: 243 },
103            LogLevel::Warning => Color::Rgb { r: 255, g: 152, b: 0 },
104            LogLevel::Watcher => Color::Rgb { r: 156, g: 39, b: 176 },
105            LogLevel::Debug => Color::Rgb { r: 103, g: 58, b: 183 },
106            LogLevel::Print => Color::Rgb { r: 255, g: 255, b: 255 },
107        };
108
109        let status = match level {
110            LogLevel::Success => "SUCCESS",
111            LogLevel::Error => "ERROR",
112            LogLevel::Info => "INFO",
113            LogLevel::Warning => "WARNING",
114            LogLevel::Watcher => "WATCHER",
115            LogLevel::Debug => "DEBUG",
116            LogLevel::Print => "PRINT",
117        };
118
119        s.push('[');
120        write!(&mut s, "{}", SetForegroundColor(color)).unwrap();
121        write!(&mut s, "{}", SetAttribute(Attribute::Bold)).unwrap();
122        s.push_str(status);
123        write!(&mut s, "{}", SetAttribute(Attribute::Reset)).unwrap();
124        s.push(']');
125        write!(&mut s, "{}", ResetColor).unwrap();
126
127        s
128    }
129
130    #[cfg(not(feature = "cli"))]
131    fn format_status(&self, level: LogLevel) -> String {
132        match level {
133            LogLevel::Success => "[SUCCESS]",
134            LogLevel::Error => "[ERROR]",
135            LogLevel::Info => "[INFO]",
136            LogLevel::Warning => "[WARNING]",
137            LogLevel::Watcher => "[WATCHER]",
138            LogLevel::Debug => "[DEBUG]",
139            LogLevel::Print => "[PRINT]",
140        }
141        .to_string()
142    }
143}