---
title: Crate features, dependencies and MSRV
description: What rtb-assets pulls into your build, which upstream features it turns on for the whole graph, the minimum supported Rust version, and how it is versioned.
tags: [reference, cargo, dependencies, msrv]
---
# Crate features, dependencies and MSRV
Everything on this page is read from `Cargo.toml`, `rust-toolchain.toml`
and `deny.toml` at version 0.6.3.
## What Cargo features does rtb-assets have?
None. `rtb-assets` declares no `[features]` table, so there is nothing
to enable, nothing to disable, and `default-features = false` changes
nothing:
```toml
[dependencies]
rtb-assets = "0.6"
```
Everything the crate can do, it does in every build. That is a
deliberate simplification for a crate this small — the cost is that the
YAML and JSON loaders, and the `miette` diagnostic machinery, come
along even if you only ever call `open`.
## What does it pull in?
| `rust-embed` | 8.12.0 | `debug-embed`, `include-exclude` | backs `EmbeddedSource` |
| `serde` | 1.0.229 | `derive` | deserialisation target for the merge loaders |
| `serde_yaml` | 0.9.34 | — | YAML parsing |
| `serde_json` | 1.0.150 | — | the merge is performed on `serde_json::Value` |
| `json-patch` | 4.2.0 | — | the RFC 7396 merge itself |
| `miette` | 7.6.0 | `fancy` | `AssetError` is a `Diagnostic` |
| `thiserror` | 2.0.19 | — | `AssetError` derivation |
There is no async runtime, no TLS stack, and no dependency back on
`rust-tool-base` — `deny.toml` bans `rust-tool-base`, `rtb-cli-bin`,
`openssl-sys` and `native-tls` outright, and `anyhow` except as a
dev-only transitive of `cucumber`. The crate is usable outside the
toolkit, which is the point of it being a crate.
## `debug-embed` is on, and that changes rust-embed's default behaviour
`rust-embed`'s default is to embed files in release builds but read
them from disk at runtime in debug builds, so you can edit an asset and
see the change without recompiling. `rtb-assets` enables the
`debug-embed` feature, which — in rust-embed's own words — means
"always embed the files in the binary, even in debug mode".
The consequences are worth being explicit about:
- **There is no dev-mode disk passthrough**, in any profile. Editing a
file under your `#[folder]` requires a rebuild for `EmbeddedSource`
to see it.
- **Cargo features are additive across the graph.** Because
`rtb-assets` turns `debug-embed` on, every other crate in your build
that uses `rust-embed` gets it too, whether or not it asked. If you
were relying on debug-mode passthrough elsewhere, adding `rtb-assets`
will quietly take it away.
- **The `#[folder]` path resolves against `Cargo.toml`** rather than
the working directory, which is the `debug-embed` behaviour in both
profiles.
To get live-editing behaviour anyway, layer a `DirectorySource` over
the embedded one and point it at the same directory in development.
[Layer precedence](../explanation/layer-precedence.md) makes the disk
copy win.
`include-exclude`, the other feature enabled here, is what lets your
own embed type carry `#[include = "*.yaml"]` and `#[exclude = "*.png"]`
attributes. Matching is on relative paths via globset, and `exclude`
beats `include`.
## `miette`'s `fancy` feature comes with it
`AssetError` derives `miette::Diagnostic`, and the dependency is
declared with the `fancy` feature, which brings the graphical report
renderer and its terminal-detection crates — `owo-colors`,
`supports-color`, `supports-hyperlinks`, `supports-unicode`,
`terminal_size`, `textwrap` and `backtrace`. Feature unification means
your build gets them even if you only ever format an `AssetError` with
`Display`.
For a CLI tool, which is what this crate was extracted from, that is
what you want. For a library or a size-sensitive binary it is a cost
you cannot currently opt out of.
## What Rust version does it need?
`rust-version = "1.82"` and `edition = "2021"`, so 1.82 is the
declared minimum for consumers.
Development is pinned separately: `rust-toolchain.toml` fixes the
toolchain to an exact **1.97.1** — not the floating `stable` channel —
with `rustfmt`, `clippy` and `rust-src`. Pinning makes a toolchain
change an intentional, reviewable merge request that Renovate opens,
rather than something that arrives on its own and breaks CI with no
source change.
Nothing in CI compiles the crate against 1.82, so treat the MSRV as a
declared intention rather than a tested guarantee. If you need it
enforced, build with `cargo +1.82 check` before depending on it.
## What lints does it hold itself to?
| `#![forbid(unsafe_code)]` | `src/lib.rs` | no `unsafe` in the shipped crate, and it cannot be re-allowed |
| `unsafe_code = "deny"` | `[lints.rust]` | package-wide, so test files can `#![allow]` where they must |
| `missing_docs = "warn"` | `[lints.rust]` | every public item carries a doc comment |
| `clippy::pedantic`, `clippy::nursery`, `clippy::cargo` | `[lints.clippy]` | warn, with `module_name_repetitions`, `missing_errors_doc`, `missing_panics_doc` and `multiple_crate_versions` allowed |
CI runs `cargo clippy --all-targets -- -D warnings`, so a warning fails
the merge gate.
## How is it versioned and released?
By [release-plz](https://release-plz.dev) from Conventional Commits — a
Release MR is kept open on `main`, and merging it publishes and tags.
Tags are per-crate, `rtb-assets-v<version>`, even though this is a
single-crate repository, to stay consistent with the rest of the Rust
toolkit. `cargo-semver-checks` vets the public API on every release, so
a breaking change to any signature on this site shows up before
publication.
Do not tag by hand.
## Known dependency risks
`serde_yaml` 0.9.34 is published as `0.9.34+deprecated`: it is
unmaintained upstream, and it is the only YAML parser here. `cargo deny
check` passes today with no advisory waivers, and `deny.toml`
deliberately carries none — if one becomes necessary it will name the
advisory, the reaching chain and a dated sunset condition.
Anything that would replace `serde_yaml` is a breaking change to the
YAML conversion table in [Merge semantics](merge-semantics.md), which
is why the current behaviour is documented there in detail rather than
described as "whatever serde_yaml does".