# Rust - Newtypes
## Resources
### (r/rust) [The newtype idiom and trait boilerplate](https://www.reddit.com/r/rust/comments/km5np7/the_newtype_idiom_and_trait_boilerplate/?utm_source=share&utm_medium=web2x&context=3)
[[2020-12-28]]
[Good comment](https://www.reddit.com/r/rust/comments/km5np7/comment/ghdd66z/?utm_source=share&utm_medium=web2x&context=3) on using `Deref` and `DerefMut`:
> One way you can make your newtypes a lot more ergonomic is by implementing [Deref](https://doc.rust-lang.org/std/ops/trait.Deref.html) and [DerefMut](https://doc.rust-lang.org/std/ops/trait.DerefMut.html) for them, then you can call all the inner type methods on your newtype, pass a reference to your newtype where the inner type is expected, and dereference your newtype to get the inner type.
>
> It's not perfect, and some people argue against it, but there usually isn't a strong reason to not implement Deref and DerefMut for newtypes unless you really want to hide the inner type as an implementation detail (such as if it's a public API and you might plan on changing the internal representation without a major version bump).
with decent links to arguments against:
- (Rust API Guidelines Book) [Only smart pointers implement `Deref` and `DerefMut`](https://rust-lang.github.io/api-guidelines/predictability.html#only-smart-pointers-implement-deref-and-derefmut-c-deref)
- States that these trait *should* only be used for smart pointers but doesn't articulate *why*
- [Stack Overflow thread](https://stackoverflow.com/questions/45086595/is-it-considered-a-bad-practice-to-implement-deref-for-newtypes)
- The top reply to the accepted answer is more popular than the accepted answer itself:
- *I have to disagree, at least in regards to `Deref` – most of my newtypes exist solely as fancy constructors, so that I can pass data around with a static guarantee that it satisfies certain invariants. I.e., once the object is constructed I no longer really care about the newtype, _only_ the underlying data; having to pattern match/`.0` everywhere is just noise, and delegating every method I might care about would be as well. I suppose it might be surprising to have a type implement `Deref` and not `DerefMut`, but they are separate traits for a reason, after all...*
- (Rust Design Patterns Book) [Deref polymorphism](https://rust-unofficial.github.io/patterns/anti_patterns/deref.html)
- Main argument against using Deref to simular inheritance is that it is implicit:
- *Rust tries to strike a careful balance between explicit and implicit mechanisms, favouring explicit conversions between types. Automatic dereferencing in the dot operator is a case where the ergonomics strongly favour an implicit mechanism, but the intention is that this is limited to degrees of indirection, not conversion between arbitrary types.*
### RFC #2393 (PR, Closed): [Delegation](https://github.com/rust-lang/rfcs/pull/2393)
- Contains the most information on delegation
### RFC #349: [Efficient code reuse](https://github.com/rust-lang/rfcs/issues/349)
- Opened on [[2014-10-02]] and still postponed, with few updates
- Contains good links to other resources
### RFC #254 (Superceded by #349): [Layout Inheritance](https://github.com/rust-lang/rfcs/pull/254)
### RFC #1406 (Closed): [delegation of impl ](https://github.com/rust-lang/rfcs/pull/1406)
- Only linked RFC that is still open is [#2431](https://github.com/rust-lang/rfcs/issues/2431)
### (Baby Steps blog post) [Virtual Structs Part 3: Bringing Enums and Structs Together](https://smallcultfollowing.com/babysteps/blog/2015/08/20/virtual-structs-part-3-bringing-enums-and-structs-together/)
[[2015-08-20]]
### (Baby Steps blog post) [Virtual Structs Part 4: Extended Enums And Thin Traits](https://smallcultfollowing.com/babysteps/blog/2015/10/08/virtual-structs-part-4-extended-enums-and-thin-traits/)
[[2015-10-08]]
### (Blog post) [Specialize to reuse](https://aturon.github.io/blog/2015/09/18/reuse/)
[[2015-09-18]]
## Possibly helpful crates
### [derive-more](https://docs.rs/derive_more/latest/derive_more/)
*Rust has lots of builtin traits that are implemented for its basic types, such as `Add`, `Not`, `From` or `Display`. However, when wrapping these types inside your own structs or enums you lose the implementations of these traits and are required to recreate them. This is especially annoying when your own structures are very simple, such as when using the commonly advised newtype pattern (e.g. `MyInt(i32)`).*
*This library tries to remove these annoyances and the corresponding boilerplate code. It does this by allowing you to derive lots of commonly used traits for both structs and enums.*
### [delegate](https://docs.rs/delegate/0.7.0/delegate/)
*This crate removes some boilerplate for structs that simply delegate some of their methods to one or more of their fields. It gives you the `delegate!` macro, which delegates method calls to selected expressions (usually inner fields).*
- Still have to write out the function signatures, which is the most annoying part of manual delegation, so IMO this crate doesn't add much value, but there are some other useful tools such as automatically calling `From` or `TryFrom` impls (but I don't see why it wouldn't just be both easier and clearer to write them out manually)