Skip to content

Commit 0223650

Browse files
committed
Remove test motivation
1 parent 78ed199 commit 0223650

File tree

1 file changed

+3
-6
lines changed

1 file changed

+3
-6
lines changed

text/3809-derive-from.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,16 @@ When using the newtype pattern, it is common to implement standard library trait
4141
struct UserId(u32);
4242
```
4343

44-
However, not all standard library traits can be derived in this way, including the `From` trait. While in some cases where the newtype might want to validate its contents (e.g. `struct Email(String)`), an implementation of `From` might not be desirable, in many cases the newtype can accept any value of the inner type, and thus implementing `From` for it is quite natural.
44+
However, not all standard library traits can be derived in this way, including the `From` trait. Currently, users have to write the boilerplate `From` implementation by hand. If there are many newtypes in a crate, this might lead users to implement a macro, which unnecessarily obfuscates the code, or use an external crate to derive the implementation, which increases code size and compile times.
4545

46-
Currently, users have to write the boilerplate `From` implementation by hand. If there are many newtypes in a crate, this might lead users to implement a macro, which unnecessarily obfuscates the code, or use an external crate to derive the implementation, which increases code size and compile times.
46+
It should be noted that there are cases where the newtype should not be able to store all possible values of the inner field, e.g. `struct Email(String)`. In that case an implementation of `From` might not be desirable, and the newtype will likely implement its own constructor function that performs validation. For cases where the newtype can represent all values of the inner field, implementing `From` for it is quite natural, as it is the designated Rust trait for performing lossless conversions.
4747

4848
Is `From` really so useful for newtypes? There are two other common alternatives for constructing a value of a newtype apart from using `From`:
49-
- Using the struct literal syntax directly, such as `UserId(5)` or `UserId { id: 5 }`. This is explicit, but it does not work in generic code (unlike `From`) and it can either only be used in the module of the struct, or the struct field has to become publicly visible, which might not be desirable.
49+
- Using the struct literal syntax directly, such as `UserId(5)` or `UserId { id: 5 }`. This is explicit, but it does not work in generic code (unlike `From`) and it can either only be used in the module of the struct, or the struct field has to become publicly visible, which is usually not desirable.
5050
- Using a constructor function, often called `new`. This function cannot be derived (without using custom proc macros) and has to be implemented using a manual `impl` block. It is essentially boilerplate code if the newtype does not need to perform any validation of the field value. If it was possible to easily derive `From`, then it could be used instead of an explicit `new` function, which could reduce the need to create any `impl` blocks for simple newtypes.
5151

5252
To summarize, if `From` was `derive`-able, it could reduce the need for using macros or external crates and increase the number of cases where `#[derive]` takes care of all required `impl`s for a given newtype.
5353

54-
### Simplifying test code
55-
Apart from the `From` trait being generally useful in various situations, it is especially handy in tests, where various fixture functions can simply receive `T: Into<Newtype>` to avoid test code having to use `.into()` or a newtype struct constructor everywhere.
56-
5754
## Why does it make sense to derive `From`?
5855
There are various "standard" traits defined in the Rust standard library that are pervasively used across the ecosystem. Currently, some of these traits can already be automatically derived, for example `Hash` or `Debug`. These traits can be derived automatically because they are composable; an implementation of the trait for a struct can be composed of the trait implementations of its fields.
5956

0 commit comments

Comments
 (0)