use std::fmt;
pub mod colors {
pub const RESET: &str = "\x1b[0m";
pub const BOLD: &str = "\x1b[1m";
pub const DIM: &str = "\x1b[2m";
pub const GREEN: &str = "\x1b[32m";
pub const YELLOW: &str = "\x1b[33m";
pub const BLUE: &str = "\x1b[34m";
pub const CYAN: &str = "\x1b[36m";
pub const RED: &str = "\x1b[31m";
pub const MAGENTA: &str = "\x1b[35m";
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MessageType {
Success,
Error,
Warning,
Info,
Tip,
Hint,
Progress,
}
impl MessageType {
pub fn icon(&self) -> &'static str {
match self {
Self::Success => "✓",
Self::Error => "✗",
Self::Warning => "⚠",
Self::Info => "ℹ",
Self::Tip => "💡",
Self::Hint => "→",
Self::Progress => "⏵",
}
}
pub fn color(&self) -> &'static str {
match self {
Self::Success => colors::GREEN,
Self::Error => colors::RED,
Self::Warning => colors::YELLOW,
Self::Info => colors::BLUE,
Self::Tip => colors::CYAN,
Self::Hint => colors::CYAN,
Self::Progress => colors::BLUE,
}
}
pub fn label(&self) -> &'static str {
match self {
Self::Success => "Success",
Self::Error => "Error",
Self::Warning => "Warning",
Self::Info => "Info",
Self::Tip => "Tip",
Self::Hint => "Hint",
Self::Progress => "Progress",
}
}
}
pub struct Message {
pub msg_type: MessageType,
pub content: String,
}
impl Message {
pub fn new(msg_type: MessageType, content: impl Into<String>) -> Self {
Self {
msg_type,
content: content.into(),
}
}
pub fn success(content: impl Into<String>) -> Self {
Self::new(MessageType::Success, content)
}
pub fn error(content: impl Into<String>) -> Self {
Self::new(MessageType::Error, content)
}
pub fn warning(content: impl Into<String>) -> Self {
Self::new(MessageType::Warning, content)
}
pub fn info(content: impl Into<String>) -> Self {
Self::new(MessageType::Info, content)
}
pub fn tip(content: impl Into<String>) -> Self {
Self::new(MessageType::Tip, content)
}
pub fn hint(content: impl Into<String>) -> Self {
Self::new(MessageType::Hint, content)
}
pub fn progress(content: impl Into<String>) -> Self {
Self::new(MessageType::Progress, content)
}
pub fn print(&self) {
println!("{}", self);
}
}
impl fmt::Display for Message {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}{}{} {}{}{}",
colors::BOLD,
self.msg_type.color(),
self.msg_type.icon(),
colors::RESET,
self.content,
colors::RESET
)
}
}
pub mod helpers {
use super::*;
pub fn success(message: impl Into<String>) {
Message::success(message).print();
}
pub fn error(message: impl Into<String>) {
Message::error(message).print();
}
pub fn warning(message: impl Into<String>) {
Message::warning(message).print();
}
pub fn info(message: impl Into<String>) {
Message::info(message).print();
}
pub fn tip(message: impl Into<String>) {
Message::tip(message).print();
}
pub fn hint(message: impl Into<String>) {
Message::hint(message).print();
}
pub fn progress(message: impl Into<String>) {
Message::progress(message).print();
}
pub fn section(title: impl Into<String>) {
let title = title.into();
println!("\n{}{}{}{}", colors::BOLD, colors::CYAN, title, colors::RESET);
println!("{}", "─".repeat(title.len()));
}
}
pub mod tips {
pub const INSTALL_TARGET: &str =
"Use 'xcargo target add <triple>' to install a new target";
pub const LIST_TARGETS: &str =
"Use 'xcargo target list' to see all available targets";
pub const CONFIG_FILE: &str =
"Create an xcargo.toml file to customize build behavior";
pub const PARALLEL_BUILDS: &str =
"Enable parallel builds in xcargo.toml with 'parallel = true' for faster builds";
pub const BUILD_CACHE: &str =
"xcargo caches builds by default. Use '--no-cache' to force a clean build";
pub const CONTAINER_BUILDS: &str =
"xcargo uses containers only when necessary. Set 'force_container = true' to always use containers";
pub const NATIVE_BUILDS: &str =
"Native builds are 2-3x faster than container builds when possible";
pub const BUILD_PROFILES: &str =
"Define custom build profiles in xcargo.toml for different scenarios (CI, release, etc.)";
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_message_types() {
assert_eq!(MessageType::Success.icon(), "✓");
assert_eq!(MessageType::Error.icon(), "✗");
assert_eq!(MessageType::Warning.icon(), "⚠");
assert_eq!(MessageType::Info.icon(), "ℹ");
assert_eq!(MessageType::Tip.icon(), "💡");
assert_eq!(MessageType::Hint.icon(), "→");
}
#[test]
fn test_message_creation() {
let msg = Message::success("Build completed");
assert_eq!(msg.msg_type, MessageType::Success);
assert_eq!(msg.content, "Build completed");
let msg = Message::tip("Use --help for more options");
assert_eq!(msg.msg_type, MessageType::Tip);
}
#[test]
fn test_message_display() {
let msg = Message::info("Testing message");
let output = format!("{}", msg);
assert!(output.contains("Testing message"));
}
}