Clean up upgrade guide, FAQ. Mention FAQ more.

This commit is contained in:
Sergio Benitez 2021-08-29 16:55:05 -07:00
parent 010e762125
commit f38cbea898
4 changed files with 118 additions and 92 deletions

View File

@ -1,12 +1,12 @@
# Upgrading # Upgrading
Rocket v0.5 bring many new features and improvements over Rocket v0.4. Along Rocket v0.5 bring many new features and improvements over Rocket v0.4. Rocket
with new features, Rocket v0.5 also includes many changes that improve the v0.5 also includes many changes that improve the overall usability, stability,
overall usability, stability, and security of the framework and applications and security of the framework and applications written in it. While the Rust
written in it. While the Rust compiler can guide you through many of these compiler can guide you through many of these changes, others require special
changes, others require special attention. The intent of this guide is to guide attention. The intent of this guide is to guide you through these changes and
you through these changes and more, migrating your Rocket application to 0.5 and more, migrating your Rocket application to 0.5 and reaping the benefits of new
reaping the benefits of new features and improvements. features and improvements.
This guide is _not_ intended to replace, but instead complement, a reading of This guide is _not_ intended to replace, but instead complement, a reading of
the [CHANGELOG]. The [CHANGELOG] should be considered required reading for all the [CHANGELOG]. The [CHANGELOG] should be considered required reading for all
@ -14,6 +14,15 @@ developers wishing to migrate their applications to Rocket v0.5.
[CHANGELOG]: @github/CHANGELOG.md [CHANGELOG]: @github/CHANGELOG.md
! note Don't panic!
Simply upgrading Rocket's version string to the `0.5` series will result in
_many_ `rustc` compiler errors. But don't let this phase you! The vast
majority of changes are simple renames and `#[async_trait]` attributions which
manifest in a cascading of errors. As such, resolving _one_ top-level issue,
typically requiring minimal, trivial changes, often resolves _many_ errors in
one go.
## Crate Organization ## Crate Organization
Rocket v0.5 incorporates an improved module structure and crate ecosystem. Rocket v0.5 incorporates an improved module structure and crate ecosystem.
@ -55,18 +64,16 @@ to `Cargo.toml`:
+ rocket_dyn_templates = { version = "0.1.0-rc.1", features = ["tera"] } + rocket_dyn_templates = { version = "0.1.0-rc.1", features = ["tera"] }
``` ```
! note: `rocket_dyn_templates` _does not_ follow in version lock-step with ! note: `rocket_dyn_templates` (and co.) _does not_ follow in version lock-step
the `rocket` crate. with the `rocket` crate.
This is intentional. The crate depends on many external dependencies which may This is intentional. The crate depends on many external dependencies which may
evolve at a different pace than Rocket itself. Allowing their versions to evolve at a different pace than Rocket itself. Allowing their versions to
diverge enables keeping dependencies up-to-date without breaking `rocket` diverge enables keeping dependencies up-to-date without breaking `rocket`
itself. itself.
All features previously present in `rocket_contrib` are available elsewhere. The All features previously in `rocket_contrib` are available. Consult the [contrib
[contrib graduation] section of the CHANGELOG contains full details on the graduation] section of the CHANGELOG for full details.
changes.
[`rocket_dyn_templates`]: @api/rocket_dyn_templates [`rocket_dyn_templates`]: @api/rocket_dyn_templates
[`rocket_sync_db_pools`]: @api/rocket_sync_db_pools [`rocket_sync_db_pools`]: @api/rocket_sync_db_pools
@ -101,7 +108,7 @@ If you prefer to use Rust's stable release channel, you can switch to it using
```sh ```sh
## switch globally ## switch globally
rustup default nightly rustup default stable
## switch locally ## switch locally
rustup override set stable rustup override set stable
@ -110,9 +117,8 @@ rustup override set stable
Using the stable release channel ensures that _no_ breakages will occur when Using the stable release channel ensures that _no_ breakages will occur when
upgrading your Rust compiler or Rocket. That being said, Rocket continues to upgrading your Rust compiler or Rocket. That being said, Rocket continues to
take advantage of features only present in the nightly channel. As a result, the take advantage of features only present in the nightly channel. As a result, the
development experience will continue to be better on nightly for the forseeable development experience will be superior on nightly for the forseeable future.
future. For example, compiler diagnostics on `nightly` are more detailed and For example, compiler diagnostics on `nightly` are more detailed and accurate:
accurate:
<details> <details>
<summary>Example Diagnostic on Nightly</summary> <summary>Example Diagnostic on Nightly</summary>
@ -179,7 +185,7 @@ The new asynchronous core requires an async runtime to run. The new
[`launch`] and [`main`] attributes simplify starting a runtime suitable for [`launch`] and [`main`] attributes simplify starting a runtime suitable for
running Rocket applications. You should use [`launch`] whenever possible. running Rocket applications. You should use [`launch`] whenever possible.
At the same time, the `rocket::ignite()` function has been renamed to Additionally, the `rocket::ignite()` function has been renamed to
[`rocket::build()`]; calls to the function or method should be replaced [`rocket::build()`]; calls to the function or method should be replaced
accordingly. Together, these two changes result in the following diff to what accordingly. Together, these two changes result in the following diff to what
was previously the `main` function: was previously the `main` function:
@ -204,18 +210,19 @@ Rocket v0.5 takes advantage of the latest developments in async I/O in Rust by
migrating to a fully asynchronous core powered by [`tokio`]. Specifically, migrating to a fully asynchronous core powered by [`tokio`]. Specifically,
_every_ request is handled by an asynchronous task which internally calls one or _every_ request is handled by an asynchronous task which internally calls one or
more request handlers. Asynchronous tasks are multiplexed on a [configurable more request handlers. Asynchronous tasks are multiplexed on a [configurable
number of worker threads]. Though there is no limit on the number of tasks that number of worker threads]. Though there is no limit to the number of tasks that
can run concurrently, at most `worker` tasks can be run in parallel. can run concurrently, at most `worker` tasks can run in parallel.
The runtime can switch between tasks in a single worker thread _iff_ an `await` The runtime can switch between tasks in a single worker thread _iff_ <small>(_if
point in reached. In other words, context switching is _cooperative_, _not_ and only if_)</small> an `await` point in reached. In other words, context
preemptive. This _iff_ is critical: if an `await` point is _not_ reached, no switching is _cooperative_, _not_ preemptive. This _iff_ is critical: if an
task switching can occur. As such, it is important that `await` points occur `await` point is _not_ reached, no task switching can occur. As such, it is
periodically in a task so that tasks waiting to be scheduled are not starved. important that `await` points occur periodically in a task so that tasks waiting
to be scheduled are not starved.
In general, when working with `async` APIs, await points will occur naturally. In general, when working with `async` APIs, await points occur naturally.
However, an application written for synchronous I/O, like all Rocket However, an application written for synchronous I/O, including all Rocket
applications prior to 0.4, must take great care to convert all synchronous, applications prior to v0.5, must take great care to convert all synchronous,
blocking I/O, to `async` I/O. This is because, as the name implies, blocking I/O blocking I/O, to `async` I/O. This is because, as the name implies, blocking I/O
blocks a thread from making progress until the I/O result is available, meaning blocks a thread from making progress until the I/O result is available, meaning
that no tasks can be scheduled on the waiting thread, wasting valuable resources that no tasks can be scheduled on the waiting thread, wasting valuable resources
@ -234,8 +241,8 @@ Common sources of blocking I/O and their `async` replacements include:
Unfortunately, the Rust compiler provides no support for identifying blocking Unfortunately, the Rust compiler provides no support for identifying blocking
I/O via lints or compile-time checks: it is up to you to scan your application I/O via lints or compile-time checks: it is up to you to scan your application
for sources of blocking I/O and replace them with their `async` counterpart. If for sources of blocking I/O and replace them with their `async` counterpart. If
no such counterpart exists, you must execute the I/O in its own thread by using no such counterpart exists, you should execute the relevant I/O in its own
[`rocket::tokio::task::spawn_blocking`]. thread by using [`rocket::tokio::task::spawn_blocking`].
All of Rocket's I/O APIs have been updated to be `async`-safe. All of Rocket's I/O APIs have been updated to be `async`-safe.
This results in requiring `.await` calls for common APIs like [`NamedFile`]. To This results in requiring `.await` calls for common APIs like [`NamedFile`]. To
@ -251,6 +258,11 @@ async fn index() -> Option<NamedFile> {
} }
``` ```
! warning: Non-`async` routes are _also_ executed on the `async` runtime.
A route that _isn't_ declared as `async` is _still_ executed on the `async`
runtime. As a result, it should not execute blocking I/O.
<details> <details>
<summary>See a diff of the changes from v0.4.</summary> <summary>See a diff of the changes from v0.4.</summary>
@ -343,7 +355,7 @@ of truth for trait and method signatures.
## Configuration ## Configuration
Rocket's configuration system has been entirely revamped for 0.5. The Rocket's configuration system has been entirely revamped for v0.5. The
[configuration](../configuration) section of the guide contains a full [configuration](../configuration) section of the guide contains a full
walkthrough of the new system while the [general changes] section of the walkthrough of the new system while the [general changes] section of the
CHANGELOG contains further details on configuration changes. We call out the CHANGELOG contains further details on configuration changes. We call out the
@ -366,7 +378,7 @@ detected.
The new system deals with "profiles" where there were previously "environments". The new system deals with "profiles" where there were previously "environments".
As opposed to environments, profiles: As opposed to environments, profiles:
* Can be arbitrarily named, and any number can exist. * Can be arbitrarily named and any number can exist.
* Match Rust profiles in naming: `debug` and `release` are the default * Match Rust profiles in naming: `debug` and `release` are the default
profiles for the respective Rust compilation profile. profiles for the respective Rust compilation profile.
* Are programmatically selectable and configurable. * Are programmatically selectable and configurable.
@ -449,7 +461,7 @@ Rocket v0.5 brings several major changes that affect routing:
Default route ranking now takes into account partially dynamic paths, increasing Default route ranking now takes into account partially dynamic paths, increasing
the range of default ranks from `[-6, -1]` to `[-12, -1]`. The net effect is the range of default ranks from `[-6, -1]` to `[-12, -1]`. The net effect is
that fewer routes collide by default, requiring less manual ranking. For that fewer routes collide by default, requiring less manual ranking. For
example, the following two routes collide in 0.4 but not in 0.5: example, the following two routes collide in v0.4 but not in v0.5:
```rust ```rust
# use rocket::get; # use rocket::get;
@ -479,7 +491,7 @@ fn everything() { }
For smaller applications, you may find that _all_ manual ranks can be removed. For smaller applications, you may find that _all_ manual ranks can be removed.
Larger applications may still require ranks to resolve ambiguities. Larger applications may still require ranks to resolve ambiguities.
### Kleen Multi-Segments ### Kleene Multi-Segments
The multi-segment route parameter `<foo..>` now matches _zero or more_ segments, The multi-segment route parameter `<foo..>` now matches _zero or more_ segments,
a change from the previous _one_ or more segments. The implication is two-fold: a change from the previous _one_ or more segments. The implication is two-fold:
@ -587,10 +599,12 @@ Rocket v0.5 introduces entirely revamped [forms] with support for:
* [Ad-Hoc validation.](../requests#ad-hoc-validation) * [Ad-Hoc validation.](../requests#ad-hoc-validation)
Additionally, the [`FromForm` derive] has been substantially improved so that Additionally, the [`FromForm` derive] has been substantially improved so that
nearly all custom implementations of `FromForm` or (the now defunct) nearly all custom implementations of `FromForm` or [`FromFormField`], which
`FromFormValue` can be derived. Altogether, this means that any external crate replaces `FromFormValue` from v0.4, can be derived. Altogether, this means that
dependency for form handling and most custom `FromForm` or `FromFormValue` any external crate dependency for form handling and most custom `FromForm` or
implementations are unnecessary and should be removed. `FromFormValue` implementations are unnecessary and should be removed.
[`FromFormField`]: @api/rocket/form/trait.FromFormField.html
### Multipart ### Multipart
@ -800,7 +814,8 @@ fn stream(n: Option<u64>) -> EventStream![] {
If you run into any issues upgrading, we encourage you to ask questions via If you run into any issues upgrading, we encourage you to ask questions via
[GitHub discussions] or via chat at [`#rocket:mozilla.org`] on Matrix or the [GitHub discussions] or via chat at [`#rocket:mozilla.org`] on Matrix or the
bridged [`#rocket`] IRC channel at `irc.libera.chat`. bridged [`#rocket`] IRC channel at `irc.libera.chat`. The [FAQ](../faq/) also
provides answers to commonly asked questions.
[GitHub discussions]: https://github.com/SergioBenitez/Rocket/discussions [GitHub discussions]: https://github.com/SergioBenitez/Rocket/discussions
[`#rocket:mozilla.org`]: https://chat.mozilla.org/#/room/#rocket:mozilla.org [`#rocket:mozilla.org`]: https://chat.mozilla.org/#/room/#rocket:mozilla.org

View File

@ -11,7 +11,8 @@ If you find yourself having trouble developing Rocket applications, you can get
help via chat at [`#rocket:mozilla.org`] on Matrix or the bridged [`#rocket`] help via chat at [`#rocket:mozilla.org`] on Matrix or the bridged [`#rocket`]
IRC channel on Libera.Chat at `irc.libera.chat`. We recommend joining us on IRC channel on Libera.Chat at `irc.libera.chat`. We recommend joining us on
[Matrix via Element]. If you prefer IRC, you can join via the [Kiwi IRC client] [Matrix via Element]. If you prefer IRC, you can join via the [Kiwi IRC client]
or a client of your own. or a client of your own. The [FAQ](../faq/) also provides answers to commonly
asked questions.
[`#rocket:mozilla.org`]: https://chat.mozilla.org/#/room/#rocket:mozilla.org [`#rocket:mozilla.org`]: https://chat.mozilla.org/#/room/#rocket:mozilla.org
[`#rocket`]: https://kiwiirc.com/client/irc.libera.chat/#rocket [`#rocket`]: https://kiwiirc.com/client/irc.libera.chat/#rocket

View File

@ -17,34 +17,35 @@ Is Rocket a monolithic framework like Rails? Or is it more like Flask?
Neither! Neither!
Rocket's core is small yet complete when it comes to security and correctness. Rocket's core is small yet complete with respect to security and correctness. It
It mainly consists of: mainly consists of:
* Guard traits like [`FromRequest`] and [`FromData`]. * Guard traits like [`FromRequest`] and [`FromData`].
* Derive macros for all commonly used traits. * Derive macros for all common traits.
* Attribute macros for routing. * Attribute macros for routing.
* Thorough compile and launch-time checking. * Thorough compile and launch-time checking.
* Optional features to enable functionality like TLS, secrets, and so on.
* Zero-copy parsers and validators for common formats like multipart and SSE. * Zero-copy parsers and validators for common formats like multipart and SSE.
* Syntax sugar extensions for features like async streams and traits. * Syntax sugar extensions for features like async streams and traits.
* Optional features for functionality like TLS, secrets, and so on.
The goal is for functionality like templating, sessions, ORMs, and so on to be The goal is for functionality like templating, sessions, ORMs, and so on to be
implemented entirely outside of Rocket and yet feel first-class. Indeed, crates implemented entirely outside of Rocket while maintaining a first-class feel and
like [`rocket_dyn_templates`] and [`rocket_db_pools`] do just this. experience. Indeed, crates like [`rocket_dyn_templates`] and [`rocket_db_pools`]
do just this. As a result, Rocket is neither "bare-bones" nor is it a kitchen
sink for all possible features.
As a result, Rocket is neither "bare-bones" nor is it a kitchen sink for all Unlike other frameworks, Rocket makes it its mission to help you avoid security
possible features. Unlike other frameworks in the Rust ecosystem, Rocket makes and correctness blunders. It does this by including, out-of-the-box:
it its mission to help you avoid security and correctness blunders
out-of-the-box. It does this by including, out-of-the-box:
* A flexible, type-based configuration system. * A flexible, type-based [configuration](../configuration/) system.
* Security and privacy headers by default. * [Security and privacy headers](@api/rocket/shield/) by default.
* Zero-Copy RFC compliant URI parsers. * Zero-Copy RFC compliant [URI parsers](@api/rocket/http/uri).
* Safe, typed URIs with compile-time checking. * Safe, [typed URIs](@api/rocket/macro.uri.html) with compile-time checking.
* Thorough compile-time and launch-time checking of routes. * [Compile-time and launch-time route checking](@api/rocket/attr.route.html).
* A complete testing framework with sync and `async` variants. * A [testing framework](@api/rocket/local) with sync and `async` variants.
* Safe, exclusive access to fully decoded HTTP values. * Safe, exclusive access to fully decoded HTTP values.
* Mandatory data limits to prevent trivial DoS attacks. * Mandatory [data limits](@api/rocket/data/struct.Limits.html) to prevent
trivial DoS attacks.
Of course, this functionality comes at a compile-time cost (but notably, _not_ Of course, this functionality comes at a compile-time cost (but notably, _not_
at a runtime cost), impacting Rocket's clean build-time. For comparison, here's at a runtime cost), impacting Rocket's clean build-time. For comparison, here's
@ -104,13 +105,15 @@ Can I use Rocket in production? Should I? It's only v0.x!
<div class="content"> <div class="content">
We **enthusiastically** recommend using Rocket in production, with the following We **enthusiastically** recommend using Rocket in production, with the following
caveats: non-exhaustive list of caveats:
1. Run Rocket behind a reverse proxy like HAProxy or in a production load 1. Run Rocket behind a reverse proxy like HAProxy or in a production load
balancing environment. Rocket (Hyper) doesn't employ any defenses against balancing environment. Rocket (Hyper) doesn't employ any defenses against
DDoS attacks or certain DoS attacks. DDoS attacks or certain DoS attacks which can be mitigated by an external
service.
2. Use a TLS termination proxy for zero-downtown certificate rotation. 2. Use a TLS termination proxy (perhaps from 1.) for zero-downtown certificate
rotation.
3. Properly configure your databases and database pools, especially with 3. Properly configure your databases and database pools, especially with
respect to the pool size. respect to the pool size.
@ -157,8 +160,8 @@ So what about benchmarks? Well, benchmarking is _hard_, and besides often being
conducted incorrectly, often appear to say more than they do. So, when you see a conducted incorrectly, often appear to say more than they do. So, when you see a
benchmark for "Hello, world!", you should know that the benchmark's relevance benchmark for "Hello, world!", you should know that the benchmark's relevance
doesn't extend far beyond "Hello, world!" servers and the specific way the doesn't extend far beyond "Hello, world!" servers and the specific way the
measurement was taken. In other words, they provide only a baseline truth that measurement was taken. In other words, it provides a baseline truth that is hard
is hard to extrapolate to real-world use-cases, _your_ use-case. to extrapolate to real-world use-cases, _your_ use-case.
Nevertheless, here are some things you can consider as _generally_ true about Nevertheless, here are some things you can consider as _generally_ true about
Rocket applications: Rocket applications:
@ -228,7 +231,8 @@ Rocket represents an ecosystem-wide effort to create a web framework that
enables writing web applications with unparalleled security, performance, and enables writing web applications with unparalleled security, performance, and
usability. From design to implementation to documentation, Rocket is carefully usability. From design to implementation to documentation, Rocket is carefully
crafted to ensure the greatest productivity and reliability with the fewest crafted to ensure the greatest productivity and reliability with the fewest
surprises. Our goal is to make Rocket the obvious choice across _all_ languages. surprises. Our goal is to make Rocket a compelling choice across _all_
languages.
Accomplishing this takes time, and our efforts extend to the entire ecosystem. Accomplishing this takes time, and our efforts extend to the entire ecosystem.
For example, work for Rocket v0.5 included: For example, work for Rocket v0.5 included:
@ -314,7 +318,7 @@ For a quick example on how to handle file uploads, see [multipart forms].
File uploads are transmitted by the browser as [multipart] form submissions, File uploads are transmitted by the browser as [multipart] form submissions,
which Rocket handles natively as a [`DataField`]. The [`TempFile`] form guard which Rocket handles natively as a [`DataField`]. The [`TempFile`] form guard
can accept a `DataField` and stream the data to disk to then be persisted. can accept a `DataField` and stream the data to disk for persistence.
</div> </div>
</details> </details>
@ -339,8 +343,8 @@ converted into useful typed values _before_ being processed. Allowing a
Instead, Rocket's handlers work through _guards_, reified as traits, which Instead, Rocket's handlers work through _guards_, reified as traits, which
validate and extract parts of a request as needed. Rocket automatically invokes validate and extract parts of a request as needed. Rocket automatically invokes
these guards for you, so custom guards are write-once-use-everywhere. Rocket these guards for you, so custom guards are write-once-use-everywhere. Rocket
won't invoke handlers that depend on guards that fail. This way, handlers only won't invoke a handler with failing guards. This way, handlers only deal with
deal with fully validated, typed, secure values. fully validated, typed, secure values.
Rocket provides all of the guard implementations you would expect Rocket provides all of the guard implementations you would expect
out-of-the-box, and you can implement your own, too. See the following: out-of-the-box, and you can implement your own, too. See the following:
@ -375,18 +379,17 @@ reasons. The rest are set by a type's [`Responder`] implementation.
**Status** **Status**
Rocket automatically sets a Status header for all responses. If the `Responder` Rocket automatically sets a `Status` header for all responses. If a `Responder`
doesn't explicitly set a status, it defaults to `200`. Responders like doesn't explicitly set a status, it defaults to `200`. Some responders, like
`Option<T>`, however, _do_ set the status. See the [`Responder`] docs for `Option<T>`, do set a status. See [`Responder`] and the [`status`] module for
details, and the [`status`] module for details on setting a custom Status or details on setting a custom `Status` or overriding an existing one.
overriding an existing one.
**Content-Type** **Content-Type**
Rocket automatically sets a Content-Type header for most types it implements Rocket automatically sets a `Content-Type` header for types it implements
`Responder` for, so in the common case, there's nothing to do. This includes `Responder` for, so in the common case, there's nothing to do. This includes
types like `&str`, `&[u8]`, `NamedFile`, and so on. The [`content`] module docs types like `&str`, `&[u8]`, `NamedFile`, and so on. The [`content`] module docs
have details on setting a custom Content-Type or overriding an existing one. details setting a custom `Content-Type` or overriding an existing one.
**Everything Else** **Everything Else**
@ -424,9 +427,10 @@ A `HeaderType` won't exist for custom headers, but you can define your own type.
As long as it implements `Into<Header>` for Rocket's [`Header`], the type can be As long as it implements `Into<Header>` for Rocket's [`Header`], the type can be
used as a field in derived struct. used as a field in derived struct.
You can always implement `Responder` directly. Make sure to leverage existing Alternatively, you can always implement `Responder` directly. Make sure to
responders in your implementation. For example, _don't_ serialize JSON manually. leverage existing responders in your implementation. For example, _don't_
Instead, use the existing [`Json`] responder, like in the example below: serialize JSON manually. Instead, use the existing [`Json`] responder, like in
the example below:
```rust ```rust
# #[derive(rocket::serde::Serialize)] # #[derive(rocket::serde::Serialize)]
@ -554,10 +558,7 @@ How do I make Rocket a _part_ of my application as opposed to the whole thing?
</summary> </summary>
<div class="content"> <div class="content">
If you're developing an application where an HTTP server is a _part_ of the Use the `#[main]` attribute and manually call [`launch()`]:
application instead of being the entire thing, use the `#[main]` attribute and
manually call [`launch()`]:
```rust,no_run ```rust,no_run
#[rocket::main] #[rocket::main]
@ -624,23 +625,29 @@ error[E0277]: the trait bound `Foo: Responder<'_, '_>` is not satisfied
= note: required by `respond_to` = note: required by `respond_to`
``` ```
...then you're almost certainly depending on libraries which depend on different ...then you're almost certainly depending, perhaps transitively, on _two
versions of `rocket`. A common mistake is to depend on a `contrib` library from different versions_ of a single library. For example, you may be depending on
git while also depending on a `crates.io` version of Rocket or vice-versa: `rocket` which depends on `time 0.3` while also depending directly on `time
0.2`. Or you may depending on `rocket` from `crates.io` while depending on a
library that depends on `rocket` from `git`. A common instance of this mistake
is to depend on a `contrib` library from git while also depending on a
`crates.io` version of Rocket or vice-versa:
```toml ```toml
rocket = "0.5.0-rc.1" rocket = "0.5.0-rc.1"
rocket_db_pools = { git = "https://github.com/SergioBenitez/Rocket.git" } rocket_db_pools = { git = "https://github.com/SergioBenitez/Rocket.git" }
``` ```
This is _never_ correct. In Rust, types from two different versions of a library This is _never_ correct. If libraries or applications interact via types from a
or from different providers (like `git` vs. `crates.io`) are _always_ considered common library, those libraries or applications _must_ specify the _same_
distinct, even if they have the same name. Therefore, even if a type implements version of that common library. This is because in Rust, types from two
a trait from one library, it _does not_ implement the trait from the other different versions of a library or from different providers (like `git` vs.
library (since it is considered to be a _different_, _distinct_ library). In `crates.io`) are _always_ considered distinct, even if they have the same name.
other words, you can _never_ mix two different published versions of Rocket, a Therefore, even if a type implements a trait from one library, it _does not_
published version and a `git` version, or two instances from different `git` implement the trait from the other library (since it is considered to be a
revisions. _different_, _distinct_ library). In other words, you can _never_ mix two
different published versions of Rocket, a published version and a `git` version,
or two instances from different `git` revisions.
</div> </div>
</details> </details>

View File

@ -14,6 +14,8 @@ aspect of Rocket. The sections are:
- **[Introduction](introduction/):** introduces Rocket and its philosophy. - **[Introduction](introduction/):** introduces Rocket and its philosophy.
- **[Quickstart](quickstart/):** presents the minimal steps necessary to - **[Quickstart](quickstart/):** presents the minimal steps necessary to
run your first Rocket application. run your first Rocket application.
- **[Upgrading from v0.4](upgrading-from-0.4/):** a migration guide from v0.4
to v0.5.
- **[Getting Started](getting-started/):** a gentle introduction to getting - **[Getting Started](getting-started/):** a gentle introduction to getting
your first Rocket application running. your first Rocket application running.
- **[Overview](overview/):** describes the core concepts of Rocket. - **[Overview](overview/):** describes the core concepts of Rocket.
@ -38,7 +40,8 @@ aspect of Rocket. The sections are:
The official community support channels are [`#rocket:mozilla.org`] on Matrix The official community support channels are [`#rocket:mozilla.org`] on Matrix
and the bridged [`#rocket`] IRC channel on Libera.Chat at `irc.libera.chat`. We and the bridged [`#rocket`] IRC channel on Libera.Chat at `irc.libera.chat`. We
recommend joining us on [Matrix via Element]. If you prefer IRC, you can join recommend joining us on [Matrix via Element]. If you prefer IRC, you can join
via the [Kiwi IRC client] or a client of your own. via the [Kiwi IRC client] or a client of your own. The [FAQ](../faq/) also
provides answers to commonly asked questions.
[`#rocket:mozilla.org`]: https://chat.mozilla.org/#/room/#rocket:mozilla.org [`#rocket:mozilla.org`]: https://chat.mozilla.org/#/room/#rocket:mozilla.org
[`#rocket`]: https://kiwiirc.com/client/irc.libera.chat/#rocket [`#rocket`]: https://kiwiirc.com/client/irc.libera.chat/#rocket