-
Notifications
You must be signed in to change notification settings - Fork 5
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
More colors and some minor changes #11
Conversation
@hanmertens Thanks so much for making this PR! I appreciate your willingness to spend time making this better. I have a couple of thoughts I'd like to discuss with you. First, I'm not sure I want to include escape sequences for anything but 24 bit colors. Mainly because I put "RGB" in the name and have tried to make it as small and focused as possible. You can see me discussing the name and purpose of this crate a while back with the owner of the rust-osdev organization here. But at the same time I'm not dead set against it because its original purpose was "support RGB colors" not "support only RGB colors". So let's continue under the assumption we'll add more than RGB. In that case I'm not sure this PR has the right abstractions. Allow me to explain. Everything boils down to this code: impl fmt::Display for EscapeCode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let base = match self.canvas {
Canvas::Background => 40,
Canvas::Foreground => 30,
};
match self.color {
Color::Color4(color4) => write!(
f,
"\x1B[{}{}m",
if color4.bright { "1;" } else { "" },
base + color4.color3 as i32
),
Color::Rgb(rgb) => write!(f, "\x1B[{};2;{};{};{}m", base + 8, rgb.r, rgb.g, rgb.b),
}
}
} That I see why you brought the concept of foreground/background into the logic that fabricates the escape codes. That's a handy abstraction that allows all the escape code logic to be in one place—let's keep that concept. So to make the code open for extension let's draw a box around that match expression and turn it into a function/trait: pub trait Color {
fn fmt(&self, f: &mut fmt::Formatter, canvas: Canvas) -> fmt::Result
} (I think the Now to add a new type of color we can just: pub struct Color8Bit {...}
impl Color for Color8Bit {
fn fmt(&self, f: &mut fmt::Formatter, canvas: Canvas) -> fmt::Result {
// todo: implement https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
}
} Hooray! Extension without modification! To make this work we'll have to tweak Now, this PR also reduces the RGB crate footprint. That's great! Thanks for that. Formatting changes. Great! I'm paid to program in another language so I'm learning how the Rust community does things.
Thoughts? Questions? |
@hanmertens I ended up putting into |
The reason I implemented struct Bold();
impl Color for Bold {
fn prelude(&self, f: &mut fmt::Formatter, _canvas: Canvas) -> fmt::Result {
f.write_str("\x1B[1m")
}
fn epilogue(&self, f: &mut fmt::Formatter, _canvas: Canvas) -> fmt::Result {
f.write_str("\x1B[0m")
}
} About the Another thing: what are your thoughts on merging the |
Good point. Although if someone really thinks it's useful to implement a trait from a crate called "ansi_rgb" in such a way that calling a function called "foreground" makes the text sprout wings and fly, more power to them. I tend to take the approach of if they really think they need to juggle with chainsaws then either they'll benefit from the lesson or they're a professional chainsaw juggler. The worst that can happen is they end up writing a monstrous application (still better than many I've written!) and their life as a programmer becomes very difficult, and they learn from it.
I like the idea. Let me chew on it for a little bit.
That wouldn't be a problem that Universal Function Call Syntax couldn't take care of. |
80647e2
to
9423d49
Compare
Disable default features as they're not used.
It should be the same for all colors, but can be overwritten this way.
3-bit colors are added as an enum, and 4-bit colors a struct contains this enum and a separate bright bit, which is not the most space-efficient.
9423d49
to
1494e9e
Compare
So I've added the 3/4-bit color types and other stuff again except the Regarding the generic formatting: using the current approach it's possible to make a more full-featured |
Sorry about moving things under your feet. I fixed the conflict.
Certainly an interesting idea. I merged what you have so far. If you want to create another PR for me to look at regarding combining the Thanks so much! |
No problem, thanks for merging. I'll have a look at combining |
I was in the need for 3/4-bit ANSI escapes for a
no_std
project, so I decided to try to add them to this crate even though they're technically notrgb
. I'm curious if you're nevertheless open to extending the crate to more color types.While working on this, I also did some unrelated minor changes that I've included:
Supertrait(reverted because it does not work; only merging theColorable
for easy importingBackground
andForeground
traits would make it possible get thefg
andbg
functions both with a single import)Convenience functions(removed, see later comments)fg_by_ref
andbg_by_ref
that borrow instead of consume the object they're coloring. I was looking for a way to makevar.fg(color)
work for non-copy owned items without running into "temporary value dropped while borrowed" #3 and this is the best thing I could think of that worked. I thinkvar.fg_by_ref(color)
looks slightly nicer than having to do(&var).fg(color)
, but it's not the elegant solution I was hoping for.rgb
crate without requiring features that are not usedLet me know if I should cherry pick only some of these or if they are better split off into a separate PR.