mikecargal

mikecargal

Hands-on Rust: RGB:named(...) not necessary?

Title: Hands-on Rust:

Always found the RGB::named(…) thing to be a bit verbose. Then I noticed that one of your examples just used WHITE, and BLACK, in their place. Now, back in chapter 9, I’m back to seeing RGB::named(…).

Marked As Solved

herbert

herbert

Author of Hands-on Rust

My goodness, you’re right. That’s somewhat embarrassing on my end. It looks like I can get rid of the RGB::named and just use the constants. (I just changed a few at random and everything still works; I’ll get this updated for the next beta). Thank you for that - it makes the code look a LOT nicer.


Some history for how I improved that without realizing I’d fixed it.

Early in bracket-lib development, the color constants were all defined as tuple triplets. For example:

pub const BISQUE: (u8, u8, u8) = (255, 228, 196);

I thought that was a bit unwieldy, because RGB back then was pretty dumb and wouldn’t work without the named constructor. I implemented the From trait for RGB, allowing it to be constructed with RGB::from(NAMED_COLOR) or NAMED_COLOR.into(). That was a bit better, and more Rusty.

Anyway, a while later the terminal gained support for alpha transparency. Suddenly, I needed RGBA and not RGB everywhere! So all of the terminal functions became generic parameters accepting any type of TryInto<RGBA> - and conversion was added for RGB <-> RGBA. That was great, because you could use whichever one suited your problem domain and it would convert between them.

Using Into and TryInto gets a little complex, but it works remarkably well. The function signature for set is as follows:

pub fn set<COLOR, COLOR2, GLYPH, X, Y>(
        &mut self,
        x: X,
        y: Y,
        fg: COLOR,
        bg: COLOR2,
        glyph: GLYPH,
    ) where
        COLOR: Into<RGBA>,
        COLOR2: Into<RGBA>,
        GLYPH: TryInto<FontCharType>,
        X: TryInto<i32>,
        Y: TryInto<i32>,
    {

See how it uses generics (like you do for Vec<T>) with an additional where constraint? The color fields will accept anything that knows how to convert into an RGBA type. (When you implement From you get Into for free - one of the few times Rust isn’t explicit). So what’s with the TryInto? I wanted the user to be able to type any type of number they wanted, rather than having to remember that x is an i32 and so on. Not all numbers are readily convertible - and some numbers may be converted for some values and not others. For example, converting a signed integer into an unsigned integer doesn’t make sense for a negative number. TryInto attempts the conversion and throws an error our if the conversion fails at runtime.

It seriously never occurred to me that because RGB/RGBA have From<(u8, u8, u8)> defined it now automatically accepted the color constants.

So thank you! I learned something and the book code will be easier to read. :slight_smile:

(Edit: I should add that using traits and making your own is planned for the next beta. They are remarkably powerful)

Where Next?

Popular Pragmatic Bookshelf topics Top

brianokken
Many tasks_proj/tests directories exist in chapters 2, 3, 5 that have tests that use the custom markers smoke and get, which are not decl...
New
GilWright
Working through the steps (checking that the Info,plist matches exactly), run the demo game and what appears is grey but does not fill th...
New
sdmoralesma
Title: Web Development with Clojure, Third Edition - migrations/create not working: p159 When I execute the command: user=&gt; (create-...
New
rmurray10127
Title: Intuitive Python: docker run… denied error (page 2) Attempted to run the docker command in both CLI and Powershell PS C:\Users\r...
New
AndyDavis3416
@noelrappin Running the webpack dev server, I receive the following warning: ERROR in tsconfig.json TS18003: No inputs were found in c...
New
curtosis
Running mix deps.get in the sensor_hub directory fails with the following error: ** (Mix) No SSH public keys found in ~/.ssh. An ssh aut...
New
AufHe
I’m a newbie to Rails 7 and have hit an issue with the bin/Dev script mentioned on pages 112-113. Iteration A1 - Seeing the list of prod...
New
rainforest
Hi, I’ve got a question about the implementation of PubSub when using a Phoenix.Socket.Transport behaviour rather than channels. Before ...
New
andreheijstek
After running /bin/setup, the first error was: The foreman' command exists in these Ruby versions: That was easy to fix: gem install fore...
New
a.zampa
@mfazio23 I’m following the indications of the book and arriver ad chapter 10, but the app cannot be compiled due to an error in the Bas...
New

Other popular topics Top

PragmaticBookshelf
Machine learning can be intimidating, with its reliance on math and algorithms that most programmers don't encounter in their regular wor...
New
PragmaticBookshelf
Learn from the award-winning programming series that inspired the Elixir language, and go on a step-by-step journey through the most impo...
New
AstonJ
I have seen the keycaps I want - they are due for a group-buy this week but won’t be delivered until October next year!!! :rofl: The Ser...
New
Exadra37
Oh just spent so much time on this to discover now that RancherOS is in end of life but Rancher is refusing to mark the Github repo as su...
New
PragmaticBookshelf
Learn different ways of writing concurrent code in Elixir and increase your application's performance, without sacrificing scalability or...
New
PragmaticBookshelf
Use WebRTC to build web applications that stream media and data in real time directly from one user to another, all in the browser. ...
New
DevotionGeo
I have always used antique keyboards like Cherry MX 1800 or Cherry MX 8100 and almost always have modified the switches in some way, like...
New
PragmaticBookshelf
Author Spotlight: Peter Ullrich @PJUllrich Data is at the core of every business, but it is useless if nobody can access and analyze ...
New
PragmaticBookshelf
Fight complexity and reclaim the original spirit of agility by learning to simplify how you develop software. The result: a more humane a...
New
PragmaticBookshelf
Use advanced functional programming principles, practical Domain-Driven Design techniques, and production-ready Elixir code to build scal...
New

Sub Categories: