I have been confused for a while on what's the best way to implement a "to string" functionality for a #Rust struct. πŸ¦€

The reason why this has been confusing to me is that there are indeed many ways to do that and they all have different purposes!

This is what I learned

πŸ‘‡πŸ§΅
The first thing that you can do is to just implement a simple `to_string()` function directly on your struct!

play.rust-lang.org/?version=stabl…
This is easy and it works! But the implementation is very specific to our struct.

The rest of the codebase doesn't really know that this type can be converted to a String and therefore you cannot build abstractions on top of this... 🀨
In fact, note how we needed to explicitly call `to_string()` in our `println!()` call.

If we try to remove that and pass the `creds` instance we get an error:

"`Credentials` cannot be formatted with the default formatter" πŸ€·β€β™€οΈ

Wouldn't it be nice if we could make this work? πŸ€”
The error itself is quite insightful. It is saying that we can make this work if we implement a specific trait for our `Credentials` struct.

In Rust, exposing certain behaviors is done by implementing specific traits. Regarding "to string" there are, in fact, a few options!
3 options (that I know about) are:

1. the std::fmt::Debug Trait
2. the std::string::ToString Trait
3. the std::fmt::Display Trait (the one recommended by our error)
Let's start with the Debug trait. The documentation says "Debug should format the output in a programmer-facing, debugging context".

This is a great way to provide details about a struct that should be visible only to developers.

play.rust-lang.org/?version=stabl…
You can generally get Rust to auto-implement the trait for you by using the Derive macro:

`#[derive(Debug)]`

Then you can print an object in debug mode by using the placeholder `{:?}` in a format string.
🀫 Small productivity tip:

You can also use the `{:#?}` placeholder (note the hash) if you want the output to be pretty-printed! 🀯
But what if we want to customize the result of Debug?

For instance, we might not want to display the full secret string but only the first 4 chars.

Well, in this case, we can implement the Debug trait manually:

play.rust-lang.org/?version=stabl…
Implementing the Debug trait manually is something that you rarely have to do manually. For the majority of use cases, the Derive macro will serve you well!

It is interesting to note that implementing the Debug trait manually requires you to use a `Formatter`. πŸ€”
From the docs: "A Formatter represents various options related to formatting. Users do not construct Formatters directly; a mutable reference to one is passed to the fmt method of all formatting traits, like Debug and Display."

More info here: doc.rust-lang.org/std/fmt/struct…
Let's now talk about the std::string::ToString trait, which is defined as:

"A trait for converting a value to a String"

But the documentation also says it shouldn’t be implemented directly. `Display` should be implemented instead & you get the ToString implementation for free!
Implementing ToString for a struct will force you to have a `to_string()` method, but the common way to tell that an object can be converted to a string is the more generic `Display` trait. We can practically ignore the `ToString` trait at this point and focus only on Display!
"Display is similar to Debug, but Display is for user-facing output, and so cannot be derived".

The documentation is essentially saying that Display allows us to provide a user-facing description of a struct and that we can only implement the trait directly, no magic derive! πŸ˜“
Let's implement Display for our Credentials struct then...

play.rust-lang.org/?version=stabl…
Note that, again, we have to deal with a formatter.

A small productivity tip is that you can use the `write!` macro with formatters and convert:

```
f.write_str(self.api_key.as_ref())
```

to

```
write!(f, "{}", self.api_key)
```

Nicer (and more flexible), isn't it? 😜
Also, remember that the placeholder to use the Display trait is just `{}` (as opposed to `{:?}` or `{:#?}` for the Debug trait).
πŸ“ƒ So, just to summarise:

- `Debug` allows you to generate debug strings. It can be automatically derived.
- `Display` is the equivalent but for user-facing information. It CANNOT be derived.
- `ToString`... don't implement it, you get it for free with `Display`!

😎
That's all I know about stringifying things in Rust! 😊

I hope this was interesting and I am curious to know if you learned something new or if all these things were already done and dusted in your Rust journey!

Did I miss or misunderstood something? plz, let me know! ❀️
If you'd like to see more of my #Rust #learning journey check out my #twitch channel, where I stream every week (Monday 5PM GMT) with @gbinside and @88_eugen our attempts at cracking the #AdventOfCode challenges using Rust!

twitch.tv/loige
And if you prefer to read rather than watching long random-ish streaming sessions, you could check out out some of my recent Rust articles on my blog:

loige.co/tag/rust

CIAO πŸ‘‹
All of this turned in a blog post: loige.co/how-to-to-stri…

β€’ β€’ β€’

Missing some Tweet in this thread? You can try to force a refresh
γ€€

Keep Current with Luciano Mammino πŸ’› Node.js

Luciano Mammino πŸ’› Node.js Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @loige

1 Oct 20
Do you know what's in a #JWT token?

Here's a quick thread to learn something about this! πŸ‘‡
A JWT token (JSON Web Token) is just a string with a well-defined format. A sample token might look like this:

```
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJoZWxsbyI6ImZyb20gSldUIn0.XoByFQCJvii_iOTO4xlz23zXmb4yuzC3gqrWNt3EHrg
```
There are 3 parts separated by a `.` (dot) character:

- header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
- body: eyJoZWxsbyI6ImZyb20gSldUIn0
- signature: XoByFQCJvii_iOTO4xlz23zXmb4yuzC3gqrWNt3EHrg
Read 13 tweets
17 Sep 20
@eleven_ty micro tip: Give eleventy some credit by injecting a "generator" meta tag in your HTML! πŸ”₯

Frontpage and Dreamweaver used to get credit this way, why shouldn't we give Eleventy some credit too? πŸ˜‡

(a short thread in 3 steps πŸ‘‡) Image
STEP 1. Create a data file in `_data/site.js` with the following content: Image
STEP 2. Create your base layout `_includes/layout.njk` and use the variable `{{ site.generator }}`: Image
Read 8 tweets
18 Aug 20
✨ Rob Pike's 5 Rules of #programming ✨

#golang #simplicity

πŸ§΅πŸ‘‡
1️⃣ You can't tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don't try to second guess and put in a speed hack until you've proven that's where the bottleneck is.
2️⃣ Measure. Don't tune for speed until you've measured, and even then don't unless one part of the code overwhelms the rest.
Read 7 tweets
11 Aug 20
Software engineering #anxiety, let's talk about it. Specifically, let me try to deconstruct my personal anxiety

πŸ§΅πŸ‘‡
1️⃣ classic impostor syndrome: it doesn't matter how good I actually am with some technology/tool/technique. Even if I can get the job done, it still feels far from adequate and I feel like I have to rush to get better to defend my job title & credibility...
2️⃣ future tech gamble: tech is always changing and I need to be ready for the next big thing if I want to stay relevant in the market. But what is the next big thing? I don't know, of course, so I try to check out as many things as I can and often end up feeling overwhelmed! 🀯
Read 6 tweets
4 Aug 20
I spoke about how #JavaScript module bundlers (those things like #Webpack) work under the hood yesterday at @coderful!

πŸ—’Here's a short-ish summary:

1/
TLDR: Module bundlers like Webpack are not "complicated" or "magic" per se, the practice of module bundling is a complicated matter and you need to understand it before you can fully understand what a module bundler does and how to configure it correctly! πŸ¦„

2/
Why do we need module bundlers? Several reasons:

- Today we rely a lot on third-party software (e.g. modules from #npm)
- There are many different standards for JavaScript modules
- We want to write code in a way that is convenient and just "compile" it for the browser

3/
Read 16 tweets
29 Jul 20
I love to use @StandardJS to enforce consistent code style in all my #JavaScript / #NodeJS projects. You can easily do that with:

```
npx standard
```

But I prefer to setup @geteslint for more extensibility.

🧡 Here's how I do it... πŸ‘‡
1. Initialize a new project with:

```
mkdir new-project
cd new-project
npm init -y
```
2. install #eslint with the following command:

```
npm i --save-dev eslint
```
Read 9 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!

Follow Us on Twitter!

:(