1#[macro_export]
3macro_rules! info {
4 ($($arg:tt)*) => {{
5 println!($($arg)*)
6 }};
7}
8
9#[macro_export]
11macro_rules! error {
12 ($($arg:tt)*) => {{
13 use colored::Colorize;
14 eprint!("{}", "[ERROR] ".red());
15 eprintln!($($arg)*)
16 }};
17}
18
19#[macro_export]
21macro_rules! usage {
22 ($($arg:tt)*) => {{
23 use colored::Colorize;
24 print!("{}", "💡 Usage: ".green());
25 println!($($arg)*)
26 }};
27}
28
29#[macro_export]
31macro_rules! debug_log {
32 ($config:expr, $($arg:tt)*) => {{
33 if $config.is_verbose() {
34 println!($($arg)*)
35 }
36 }};
37}
38
39#[macro_export]
43macro_rules! md {
44 ($($arg:tt)*) => {{
45 let text = format!($($arg)*);
46 $crate::util::log::render_md(&text);
47 }};
48}
49
50#[macro_export]
52macro_rules! md_inline {
53 ($($arg:tt)*) => {{
54 let text = format!($($arg)*);
55 termimad::print_inline(&text);
56 }};
57}
58
59#[allow(dead_code)]
61pub fn print_line() {
62 println!("- - - - - - - - - - - - - - - - - - - - - - -");
63}
64
65pub fn capitalize_first_letter(s: &str) -> String {
67 let mut chars = s.chars();
68 match chars.next() {
69 None => String::new(),
70 Some(c) => c.to_uppercase().collect::<String>() + chars.as_str(),
71 }
72}
73
74#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
77const ASK_BINARY: &[u8] = include_bytes!("../../plugin/ask/bin/ask-darwin-arm64");
78
79fn get_ask_path() -> Option<std::path::PathBuf> {
82 #[cfg(not(all(target_os = "macos", target_arch = "aarch64")))]
83 {
84 return None;
85 }
86
87 #[cfg(all(target_os = "macos", target_arch = "aarch64"))]
88 {
89 use std::os::unix::fs::PermissionsExt;
90
91 let data_dir = crate::config::YamlConfig::data_dir();
92 let bin_dir = data_dir.join("bin");
93 let ask_path = bin_dir.join("ask");
94
95 if ask_path.exists() {
96 if let Ok(meta) = std::fs::metadata(&ask_path) {
98 if meta.len() == ASK_BINARY.len() as u64 {
99 return Some(ask_path);
100 }
101 }
102 }
103
104 if std::fs::create_dir_all(&bin_dir).is_err() {
106 return None;
107 }
108 if std::fs::write(&ask_path, ASK_BINARY).is_err() {
109 return None;
110 }
111 if let Ok(meta) = std::fs::metadata(&ask_path) {
113 let mut perms = meta.permissions();
114 perms.set_mode(0o755);
115 let _ = std::fs::set_permissions(&ask_path, perms);
116 }
117
118 Some(ask_path)
119 }
120}
121
122pub fn render_md(text: &str) {
126 use std::io::Write;
127 use std::process::{Command, Stdio};
128
129 let ask_path = get_ask_path();
131
132 if let Some(path) = ask_path {
133 let result = Command::new(&path)
135 .stdin(Stdio::piped())
136 .stdout(Stdio::inherit())
137 .stderr(Stdio::inherit())
138 .spawn();
139
140 match result {
141 Ok(mut child) => {
142 if let Some(mut stdin) = child.stdin.take() {
143 let _ = stdin.write_all(text.as_bytes());
144 drop(stdin);
145 }
146 let _ = child.wait();
147 return;
148 }
149 Err(_) => {}
150 }
151 }
152
153 termimad::print_text(text);
155}