An open source book about design patterns and idioms in the Rust programming
language that you can read [here](https://rust-unofficial.github.io/patterns/).
## TODOs
### Idioms
* TODO stability for extensibility
* TODO trait to separate visibility of methods from visibility of data (https://github.com/sfackler/rust-postgres/blob/v0.9.6/src/lib.rs#L1400)
* TODO trait to separate visibility of methods from visibility of data (<https://github.com/sfackler/rust-postgres/blob/v0.9.6/src/lib.rs#L1400>)
* TODO leak amplification ("Vec::drain sets the Vec's len to 0 prematurely so that mem::forgetting Drain "only" mem::forgets more stuff. instead of exposing uninitialized memory or having to update the len on every iteration")
* TODO interior mutability - UnsafeCell, Cell, RefCell
* TODO FFI usage (By being mindful of how to provide Rust libraries, and make use of existing libraries across the FFI, you can get more out of benefits Rust can bring)
### Design patterns
* TODO iterators (to safely avoid bounds checks)
* TODO closures and lifetimes (coupling to lifetime)
* TODO platform-specific sub-modules (https://github.com/rust-lang/rfcs/blob/master/text/0517-io-os-reform.md#platform-specific-opt-in)
* TODO platform-specific sub-modules (<https://github.com/rust-lang/rfcs/blob/master/text/0517-io-os-reform.md#platform-specific-opt-in>)
* TODO Module organisation (by looking at examples such as Rusts `libstd`, and how it integrated into the Rusts source code, lessons can be learned about ergonomic project management and API design. Closely assosciated with platform-specific sub-modules)
* [Entry API](patterns/entry.md) (Currently just a boilerplate)
* TODO extension traits
* TODO destructor bombs (ensure linear typing dynamically, e.g., https://github.com/Munksgaard/session-types/commit/0f25ccb7c3bc9f65fa8eaf538233e8fe344a189a)
* TODO convertible to Foo trait for more generic generics (e.g., http://static.rust-lang.org/doc/master/std/fs/struct.File.html#method.open)
* TODO destructor bombs (ensure linear typing dynamically, e.g., <https://github.com/Munksgaard/session-types/commit/0f25ccb7c3bc9f65fa8eaf538233e8fe344a189a>)
* TODO convertible to Foo trait for more generic generics (e.g., <http://static.rust-lang.org/doc/master/std/fs/struct.File.html#method.open>)
* [Late bound bounds](patterns/late-bounds.md) (Currently just a boilerplate)
* TODO 'shadow' borrowed version of struct - e.g., double buffering, Niko's parser generator
* TODO composition of structs to please the borrow checker
* TODO `Error` traits and `Result` forwarding
* TODO graphs
### Anti-patterns
* TODO thread + catch_panic for exceptions
@ -41,7 +38,6 @@ language that you can read [here](https://rust-unofficial.github.io/patterns/).
* TODO taking an enum rather than having multiple functions
* TODO `unwrap()`ing every `Result` instead of forwarding it
## Contributing
You are missing content in this repository that can be helpful for others and you are eager to explain it?
@ -49,7 +45,6 @@ Awesome! We are always happy about new contributions (e.g. elaboration or correc
We suggest reading our [Contribution guide](./CONTRIBUTING.md) to get more information on how it works.
## Building with mdbook
This book is built with [mdbook](https://rust-lang.github.io/mdBook/). You can install it by running `cargo install mdbook`.
@ -65,7 +60,6 @@ If you want to build it locally you can run one of these two commands in the roo
Serves the book at `http://localhost:3000` (port is changeable, take a look at the terminal output
to be sure) and reloads the browser when a change occurs.
## License
This content of this repository is licensed under **MPL-2.0**; see [LICENSE](./LICENSE).
@ -113,5 +113,6 @@ However, this example will not run when our function is declared with an argumen
This is because string slices are a `&str` and not a `&String` which would require an allocation to be converted to `&String` which is not implicit, whereas converting from `String` to `&str` is cheap and implicit.
## See also
- [Rust Language Reference on Type Coercions](https://doc.rust-lang.org/reference/type-coercions.html)
- For more discussion on how to handle `String` and `&str` see [this blog series (2015)](https://web.archive.org/web/20201112023149/https://hermanradtke.com/2015/05/03/string-vs-str-in-rust-functions.html) by Herman J. Radtke III.
@ -6,6 +6,7 @@ If a struct takes significant effort to initialize, when writing docs, it can be
function which takes the struct as an argument.
## Motivation
Sometimes there is a struct with multiple or complicated parameters and several methods.
Each of these methods should have examples.
@ -41,6 +42,7 @@ impl Connection {
```
## Example
Instead of typing all of this boiler plate to create an `Connection` and `Request` it is easier to just create a wrapping dummy function which takes them as arguments:
```rust,ignore
@ -64,6 +66,7 @@ impl Connection {
}
}
```
**Note** in the above example the line `assert!(response.is_ok());` will not actually run while testing because it is inside of a function which is never invoked.
When developing programs, we have to solve many problems. A program can be viewed as a solution to a problem. It can also be viewed as a collection of solutions to many different problems. All of these solutions work together to solve a bigger problem.
The primary motivation for newtypes is abstraction. It allows you to share
@ -63,7 +62,6 @@ API, it allows you to change implementation backwards compatibly.
Newtypes can be used for distinguishing units, e.g., wrapping `f64` to give
distinguishable `Miles` and `Kms`.
## Advantages
The wrapped and wrapper types are not type compatible (as opposed to using
@ -83,7 +81,6 @@ You need a 'pass through' method for every method you want to expose on the
wrapped type, and an impl for every trait you want to also be implemented for
the wrapper type.
## Discussion
Newtypes are very common in Rust code. Abstraction or representing units are the
@ -99,7 +96,6 @@ pub struct Foo(Bar<T1, T2>);
Here, `Bar` might be some public, generic type and `T1` and `T2` are some internal types. Users of our module shouldn't know that we implement `Foo` by using a `Bar`, but what we're really hiding here is the types `T1` and `T2`, and how they are used with `Bar`.
## See also
- [Advanced Types in the book](https://doc.rust-lang.org/book/ch19-04-advanced-types.html?highlight=newtype#using-the-newtype-pattern-for-type-safety-and-abstraction)