comfy_print_sync/
sync_impl.rs1use super::utils;
2use super::utils::Message;
3use parking_lot::FairMutex;
4
5static QUEUE: FairMutex<Vec<Message>> = FairMutex::new(Vec::new());
6use std::sync::atomic::{AtomicBool, Ordering};
7
8static IS_PRINTING: AtomicBool = AtomicBool::new(false);
9
10#[allow(unused_must_use)]
11pub fn _comfy_print_sync(msg: Message) {
12 let mut queue_guard = QUEUE.lock();
13
14 if queue_guard.len() == 0 {
15 drop(queue_guard);
16 write_first_in_line(msg);
17 } else {
18 queue_guard.push(msg);
19 drop(queue_guard);
20 if let Ok(_) = IS_PRINTING.compare_exchange(false, true, Ordering::AcqRel, Ordering::Relaxed) {
21 write_until_empty();
22 }
23 }
24}
25
26fn write_until_empty() {
27 loop {
28 let mut queue_guard = QUEUE.lock();
29
30 if queue_guard.len() == 0 {
31 drop(queue_guard);
32 break;
33 }
34
35 let msg = queue_guard.remove(0);
36 drop(queue_guard);
37 let msg_str: &str = msg.str();
38 let output_kind = msg.output_kind();
39
40 let write_result = utils::try_write(&msg_str, output_kind);
41
42 if let Err(err) = write_result {
43 let mut queue_guard = QUEUE.lock();
44 queue_guard.insert(0, Message::error(format!(
45 "comfy_print::write_until_empty(): Failed to print first message in queue, it was pushed to the front again.\n\
46 Error: {err}\n\
47 Message: {msg_str}\n\
48 Target output: {output_kind:?}")));
49
50 queue_guard.insert(1, msg);
51 drop(queue_guard);
52 break;
53 }
54 }
55
56 IS_PRINTING.store(false, Ordering::Relaxed); }
58
59fn write_first_in_line(msg: Message) {
61 let msg_str: &str = msg.str();
62
63 if let Err(err) = utils::try_write(&msg_str, msg.output_kind()) {
64 let mut queue_guard = QUEUE.lock();
65 queue_guard.insert(0, Message::error(format!(
66 "comfy_print::blocking_write_first_in_line(): Failed to print first message in queue, it was pushed to the front again.\n\
67 Error: {err}\n\
68 Message: {msg_str}")));
69
70 queue_guard.insert(1, msg);
71 drop(queue_guard);
72 }
73}
74
75pub fn _println(mut input: String) {
76 input.push('\n');
77 _comfy_print_sync(Message::standard(input));
78}
79
80pub fn _print(input: String) {
81 _comfy_print_sync(Message::standard(input));
82}
83
84pub fn _eprint(input: String) {
85 _comfy_print_sync(Message::error(input));
86}
87
88pub fn _eprintln(mut input: String) {
89 input.push('\n');
90 _comfy_print_sync(Message::error(input));
91}
92
93#[macro_export]
94macro_rules! comfy_print {
95 ($($arg:tt)*) => {{
96 $crate::sync_impl::_print(std::format!($($arg)*));
97 }};
98}
99
100#[macro_export]
101macro_rules! comfy_println {
102 () => {
103 $crate::sync_impl::_println("\n")
104 };
105 ($($arg:tt)*) => {{
106 $crate::sync_impl::_println(std::format!($($arg)*));
107 }};
108}
109
110#[macro_export]
111macro_rules! comfy_eprint {
112 ($($arg:tt)*) => {{
113 $crate::sync_impl::_eprint(std::format!($($arg)*));
114 }};
115}
116
117#[macro_export]
118macro_rules! comfy_eprintln {
119 () => {
120 $crate::sync_impl::_eprintln("\n")
121 };
122 ($($arg:tt)*) => {{
123 $crate::sync_impl::_eprintln(std::format!($($arg)*));
124 }};
125}