Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide fmt::Write API #123

Open
stefnotch opened this issue Mar 19, 2024 · 3 comments
Open

Provide fmt::Write API #123

stefnotch opened this issue Mar 19, 2024 · 3 comments

Comments

@stefnotch
Copy link

stefnotch commented Mar 19, 2024

The crate tracing-subscriber might switch to using owo-colors. ( tokio-rs/tracing#2759 )

I tried implementing it, but stumbled upon a tricky case. Essentially tracing-subscriber is outputting values to a core::fmt::Write, and it wants to call fmt_prefix before that and fmt_suffix after that.[1]
However, the fmt_prefix and fmt_suffix methods assume that one has a std::fmt::Formatter. Which isn't the case here. The code is roughly

write!(writer, "{}", style.prefix())?;

// Directly prints to the writer. No instance of std::fmt::Formatter exists here.
self.timer.format_time(writer)

write!(writer, "{} ", style.suffix())?;

Would it be reasonable to change the fmt_prefix/fmt_suffix methods to accept anything that implements fmt::Write? Or is there another, potentially better solution?

[1]
https://github.com/tokio-rs/tracing/blob/908cc432a5994f6e17c8f36e13c217dc40085704/tracing-subscriber/src/fmt/format/mod.rs#L859-L868

@stefnotch
Copy link
Author

I'm currently using the following workaround. Ended up being surprisingly neat.

struct FormatTimeDisplay<T>(T);
impl<T: FormatTime> fmt::Display for FormatTimeDisplay<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.0.format_time(&mut Writer::new(f)).is_err() {
            f.write_str("<unknown time>")
        } else {
            Ok(())
        }
    }
}

@sunshowers
Copy link
Collaborator

@stefnotch yeah I encountered this the other day too, and used the same approach you did with a wrapper type's Display impl. What do you think of providing a wrapper within owo-colors itself? (I'd personally rather not break any APIs and keep owo-colors at 4.x indefinitely)

@stefnotch
Copy link
Author

That could be neat.

While working with styling crates, I've heard of two wildly different wishes. Depending on those, one would design a different API

  1. Low level ANSI control, with minimal extra characters. Things like "start green, text, start bold, text, turn both styles off". That almost certainly requires an API where the consumer can control the start and end separately. This API is also harder to use correctly.
  • Alternative outputs. Quite a few crates don't actually care as much about outputting ANSI as they care about outputting styled text that the user can use. If the crate is used in a browser environment, then outputting HTML tags instead of ANSI can be a very reasonable choice. That requires a design closer to owo-colors, but with a replaceable backend.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants