nicoburns / blessed-rs

A community guide to the Rust ecosystem
https://blessed.rs
1.17k stars 66 forks source link

Revisit recommended text colouring crate #100

Open russellbanks opened 6 months ago

russellbanks commented 6 months ago

colored-rs/colored (https://lib.rs/crates/colored) seems like it would a better fit to recommend for colouring text on a terminal than termcolor. It has 3.5x the GitHub stars of termcolor as of this issue. I think that both should be recommended or that colored should replace termcolor. The linked page for termcolor on lib.rs has also been removed.

I initially came across colored myself from this stackoverflow answer that recommends it.

nicoburns commented 6 months ago

I've also seen https://github.com/jam1garner/owo-colors recommended. Which bills itself as a drop-in replacement for colored, but with no_std support. Thoughts?

epage commented 6 months ago

imo most approaches to coloring are flawed because they require you to know what you are rendering to (stdout, stderr, a file, etc). I've created anstream as a wrapper around output sinks that auto-adapts the content to what you are writing to. In these scenarios, you always write colored output and don't worry about. burntsushi has expressed interest in this as a potential replacement for termcolor. anstream also has the bonus of including the functionality for strip-ansi-escapes while being significantly faster.

The download count is high but that is biased by it being used in some high-download count packages.

It has recently been adopted in cargo but that is also biased by the fact that I'm on the cargo team. If curious, rust-lang/cargo#12751 is where I converted cargo from termcolor to anstream.

A color rendering library is still needed. Depending on what I need, I tend to use a mixture of anstyle (lightweight), color-print (compile-time rendering), and owo-colors (without the extra adapting features).

russellbanks commented 6 months ago

colored could be the recommendation for std enviroments and owo-colors the recommendation for no_std enviromments and embedded systems?

I haven't used owo-colors myself but from looking into it, colored still seems to make the most sense in enviroments that aren't embedded systems or no_std:

epage commented 6 months ago

It looks like the main difference between colored and owo-colors is who controls coloring. With colored, it has some limited auto-selection code with a global override while owo-colors leaves it up to the caller / output sink. I'm biased but with anstream, my preference is towards owo-colors.

An odd point about colored is that the global control is stored inside of the same crate, meaning that if they break compatibility, you can be controlling it in one version of the package but its being read in a different. This is why I created the colorchoice crate.

BurntSushi commented 6 months ago

Author of termcolor here.

I don't know what the criteria is for whether a crate is "blessed" or not, but I presume termcolor was listed because it was the de facto standard choice if you wanted coloring to be as broadly applicable as possible, and because it was used by rustc, cargo and ripgrep. That is, it is battle tested. The "broad applicability" refers to the fact that it doesn't just color things via ANSI escape codes, but will also work on legacy Windows consoles that don't support ANSI escapes. It's unclear whether colored supports that or not.

These days, support for legacy Windows consoles is getting less and less important. I myself am eager to drop it and just fall back to emitting ANSI escapes manually through some custom hand-rolled code inside of ripgrep.

I do like @epage's approach personally, but the dependency tree of anstream is a bit too much for me, especially if I can eventually switch over to just writing ANSI escape codes manually.

I don't know how to pick which of these choices is "blessed," but IMO the curator should express an opinion and choose one. I myself am eager to deprecate termcolor once support for legacy Windows consoles is no longer desirable. (I don't know exactly when that will be. It's hard to know. But IIRC, ANSI escape support was added to Windows 10 at some point.)

epage commented 6 months ago

but the dependency tree of anstream is a bit too much for me, especially if I can eventually switch over to just writing ANSI escape codes manually.

I'm not responding directly to @BurntSushi but to those who might get the wrong impression by this. Note that a valid alternative given is directly writing ANSI escape codes, ie not even having owo-colors, etc. The important question is "how do you quantify a bit much". Too many people incorrectly look to dependency count. That is misleading as things that were baked into termcolor, anstream splits out into crates. Its like splitting a chocolate bar in half and thinking there is now more chocolate bar. That doesn't account for all dependencies but overall, the dependencies are fairly "light" in amount of code and tree is broad, allowing parallelism. As build times and binary size are a sensitive topic for clap, I kept a close eye on anstreams affect on those metrics for clap.

epage commented 6 months ago

The "broad applicability" refers to the fact that it doesn't just color things via ANSI escape codes, but will also work on legacy Windows consoles that don't support ANSI escapes. It's unclear whether colored supports that or not.

Note that anstream implicitly handles legacy Windows consoles so pairing it with an appropriate library like owo-colors or anstyle takes care of that for you.

bzm3r commented 6 months ago

Neither colored nor owo-colors handle things like emitting hyperlinks, or window titles (something that the older ansi_term and its descendants do) --- is there a reason for that, or a crate one should use? Could that also be included in the blessed list?

BurntSushi commented 6 months ago

termcolor does have hyperlink support (to support a corresponding feature in ripgrep): https://docs.rs/termcolor/latest/termcolor/trait.WriteColor.html#method.set_hyperlink

nicoburns commented 6 months ago

To help frame the discussion: the motivation behind setting up blessed.rs was the frequent complaints from members of the community (or would-be members of the community) that Rust's std library was too small, that the crates.io ecosystem was overwhelming, and that it was difficult both to discover the "de facto standard" crates and to know which crates were trustworthy, likely to be maintained, etc.

Blessed definitely isn't supposed to be a list of every crate in a category. It attempts to be somewhat opinionated in order to help readers make decisions. Having said that, if there are libraries with different trade offs and no clear winner, then there also doesn't need to be strictly one options listed. It seems to me that it would reasonable for blessed's recommendation to be something like Crate X if you need windows console compatibility, otherwise Crate Y.