Question
I'm wondering if there is a way to improve the current structure of some functions in my program since I feel there is a fair amount of unwanted repetition happening.
Background
I'm writing a tiny logger so CLI applications can have prettier text in the terminal. I have a couple functions that add some icons to what is going to stdout such as success()
, it takes a message and adds a green checkmark icon to it, same with error()
, warn()
etc. They can all either add a newline character at the end or ignore it depending on if the user called same()
before it.
Currently they use the three functions defined below to decide whether or not to add a newline, and whether or not to add a timestamp.
Code
/// Outputs to stdout with an icon
fn output<T: Display>(&mut self, message: T, icon: LogIcon) {
let timestamp = self.timestamp();
if self.same_line {
print!("{} {}{}", icon, timestamp, message);
} else {
println!("{} {}{}", icon, timestamp, message);
}
self.same_line = false;
}
/// Outputs to stderr with an icon
fn output_error<T: Display>(&mut self, message: T, icon: LogIcon) {
let timestamp = self.timestamp();
if self.same_line {
eprint!("{} {}{}", icon, timestamp, message);
} else {
eprintln!("{} {}{}", icon, timestamp, message);
}
self.same_line = false;
}
/// Outputs to stdout normally
fn output_normal<T: Display>(&mut self, message: T) {
let timestamp = self.timestamp();
if self.same_line {
print!("{}{}", timestamp, message);
} else {
println!("{}{}", timestamp, message);
}
self.same_line = false;
}
This is how the success
function makes use of output function at the moment:
pub fn success<T: Display>(&mut self, message: T) {
self.output(message, LogIcon::CheckMark);
}
The same applies for all other functions, they either output to stderr
or stdout
.