agy-superpowers 5.2.2 → 5.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -150
- package/package.json +1 -1
- package/template/agent/rules/scratch-scripts.md +37 -0
- package/template/agent/rules/superpowers.md +4 -51
- package/template/agent/skills/ai-integrated-product/SKILL.md +0 -57
- package/template/agent/skills/analytics-setup/SKILL.md +0 -51
- package/template/agent/skills/api-design/SKILL.md +0 -193
- package/template/agent/skills/app-store-optimizer/SKILL.md +0 -127
- package/template/agent/skills/auth-and-identity/SKILL.md +0 -167
- package/template/agent/skills/backend-developer/SKILL.md +0 -148
- package/template/agent/skills/bootstrapper-finance/SKILL.md +0 -55
- package/template/agent/skills/chrome-extension-developer/SKILL.md +0 -53
- package/template/agent/skills/community-manager/SKILL.md +0 -115
- package/template/agent/skills/content-marketer/SKILL.md +0 -111
- package/template/agent/skills/conversion-optimizer/SKILL.md +0 -142
- package/template/agent/skills/cto-architect/SKILL.md +0 -133
- package/template/agent/skills/customer-success-manager/SKILL.md +0 -126
- package/template/agent/skills/data-analyst/SKILL.md +0 -147
- package/template/agent/skills/devops-engineer/SKILL.md +0 -117
- package/template/agent/skills/email-infrastructure/SKILL.md +0 -164
- package/template/agent/skills/game-design/SKILL.md +0 -194
- package/template/agent/skills/game-developer/SKILL.md +0 -175
- package/template/agent/skills/growth-hacker/SKILL.md +0 -122
- package/template/agent/skills/idea-validator/SKILL.md +0 -55
- package/template/agent/skills/indie-legal/SKILL.md +0 -53
- package/template/agent/skills/influencer-marketer/SKILL.md +0 -141
- package/template/agent/skills/landing-page-builder/SKILL.md +0 -59
- package/template/agent/skills/launch-strategist/SKILL.md +0 -62
- package/template/agent/skills/market-researcher/SKILL.md +0 -53
- package/template/agent/skills/micro-saas-builder/SKILL.md +0 -56
- package/template/agent/skills/monetization-strategist/SKILL.md +0 -119
- package/template/agent/skills/paid-acquisition-specialist/SKILL.md +0 -119
- package/template/agent/skills/pricing-psychologist/SKILL.md +0 -58
- package/template/agent/skills/real-time-features/SKILL.md +0 -194
- package/template/agent/skills/retention-specialist/SKILL.md +0 -123
- package/template/agent/skills/rust-developer/SKILL.md +0 -281
- package/template/agent/skills/rust-developer/references/rust-rules/_sections.md +0 -231
- package/template/agent/skills/rust-developer/references/rust-rules/anti-clone-excessive.md +0 -124
- package/template/agent/skills/rust-developer/references/rust-rules/anti-collect-intermediate.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/anti-empty-catch.md +0 -132
- package/template/agent/skills/rust-developer/references/rust-rules/anti-expect-lazy.md +0 -95
- package/template/agent/skills/rust-developer/references/rust-rules/anti-format-hot-path.md +0 -141
- package/template/agent/skills/rust-developer/references/rust-rules/anti-index-over-iter.md +0 -125
- package/template/agent/skills/rust-developer/references/rust-rules/anti-lock-across-await.md +0 -127
- package/template/agent/skills/rust-developer/references/rust-rules/anti-over-abstraction.md +0 -120
- package/template/agent/skills/rust-developer/references/rust-rules/anti-panic-expected.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/anti-premature-optimize.md +0 -156
- package/template/agent/skills/rust-developer/references/rust-rules/anti-string-for-str.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/anti-stringly-typed.md +0 -167
- package/template/agent/skills/rust-developer/references/rust-rules/anti-type-erasure.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/anti-unwrap-abuse.md +0 -143
- package/template/agent/skills/rust-developer/references/rust-rules/anti-vec-for-slice.md +0 -121
- package/template/agent/skills/rust-developer/references/rust-rules/api-builder-must-use.md +0 -143
- package/template/agent/skills/rust-developer/references/rust-rules/api-builder-pattern.md +0 -187
- package/template/agent/skills/rust-developer/references/rust-rules/api-common-traits.md +0 -165
- package/template/agent/skills/rust-developer/references/rust-rules/api-default-impl.md +0 -177
- package/template/agent/skills/rust-developer/references/rust-rules/api-extension-trait.md +0 -163
- package/template/agent/skills/rust-developer/references/rust-rules/api-from-not-into.md +0 -146
- package/template/agent/skills/rust-developer/references/rust-rules/api-impl-asref.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/api-impl-into.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/api-must-use.md +0 -125
- package/template/agent/skills/rust-developer/references/rust-rules/api-newtype-safety.md +0 -162
- package/template/agent/skills/rust-developer/references/rust-rules/api-non-exhaustive.md +0 -177
- package/template/agent/skills/rust-developer/references/rust-rules/api-parse-dont-validate.md +0 -184
- package/template/agent/skills/rust-developer/references/rust-rules/api-sealed-trait.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/api-serde-optional.md +0 -182
- package/template/agent/skills/rust-developer/references/rust-rules/api-typestate.md +0 -199
- package/template/agent/skills/rust-developer/references/rust-rules/async-bounded-channel.md +0 -175
- package/template/agent/skills/rust-developer/references/rust-rules/async-broadcast-pubsub.md +0 -185
- package/template/agent/skills/rust-developer/references/rust-rules/async-cancellation-token.md +0 -203
- package/template/agent/skills/rust-developer/references/rust-rules/async-clone-before-await.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/async-join-parallel.md +0 -158
- package/template/agent/skills/rust-developer/references/rust-rules/async-joinset-structured.md +0 -195
- package/template/agent/skills/rust-developer/references/rust-rules/async-mpsc-queue.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/async-no-lock-await.md +0 -156
- package/template/agent/skills/rust-developer/references/rust-rules/async-oneshot-response.md +0 -191
- package/template/agent/skills/rust-developer/references/rust-rules/async-select-racing.md +0 -198
- package/template/agent/skills/rust-developer/references/rust-rules/async-spawn-blocking.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-fs.md +0 -167
- package/template/agent/skills/rust-developer/references/rust-rules/async-tokio-runtime.md +0 -169
- package/template/agent/skills/rust-developer/references/rust-rules/async-try-join.md +0 -172
- package/template/agent/skills/rust-developer/references/rust-rules/async-watch-latest.md +0 -189
- package/template/agent/skills/rust-developer/references/rust-rules/doc-all-public.md +0 -113
- package/template/agent/skills/rust-developer/references/rust-rules/doc-cargo-metadata.md +0 -147
- package/template/agent/skills/rust-developer/references/rust-rules/doc-errors-section.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/doc-examples-section.md +0 -161
- package/template/agent/skills/rust-developer/references/rust-rules/doc-hidden-setup.md +0 -149
- package/template/agent/skills/rust-developer/references/rust-rules/doc-intra-links.md +0 -138
- package/template/agent/skills/rust-developer/references/rust-rules/doc-link-types.md +0 -169
- package/template/agent/skills/rust-developer/references/rust-rules/doc-module-inner.md +0 -116
- package/template/agent/skills/rust-developer/references/rust-rules/doc-panics-section.md +0 -128
- package/template/agent/skills/rust-developer/references/rust-rules/doc-question-mark.md +0 -136
- package/template/agent/skills/rust-developer/references/rust-rules/doc-safety-section.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/err-anyhow-app.md +0 -179
- package/template/agent/skills/rust-developer/references/rust-rules/err-context-chain.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/err-custom-type.md +0 -152
- package/template/agent/skills/rust-developer/references/rust-rules/err-doc-errors.md +0 -145
- package/template/agent/skills/rust-developer/references/rust-rules/err-expect-bugs-only.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/err-from-impl.md +0 -152
- package/template/agent/skills/rust-developer/references/rust-rules/err-lowercase-msg.md +0 -124
- package/template/agent/skills/rust-developer/references/rust-rules/err-no-unwrap-prod.md +0 -115
- package/template/agent/skills/rust-developer/references/rust-rules/err-question-mark.md +0 -151
- package/template/agent/skills/rust-developer/references/rust-rules/err-result-over-panic.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/err-source-chain.md +0 -155
- package/template/agent/skills/rust-developer/references/rust-rules/err-thiserror-lib.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/lint-cargo-metadata.md +0 -138
- package/template/agent/skills/rust-developer/references/rust-rules/lint-deny-correctness.md +0 -107
- package/template/agent/skills/rust-developer/references/rust-rules/lint-missing-docs.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/lint-pedantic-selective.md +0 -118
- package/template/agent/skills/rust-developer/references/rust-rules/lint-rustfmt-check.md +0 -157
- package/template/agent/skills/rust-developer/references/rust-rules/lint-unsafe-doc.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-complexity.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-perf.md +0 -136
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-style.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/lint-warn-suspicious.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/lint-workspace-lints.md +0 -172
- package/template/agent/skills/rust-developer/references/rust-rules/mem-arena-allocator.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/mem-arrayvec.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/mem-assert-type-size.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/mem-avoid-format.md +0 -147
- package/template/agent/skills/rust-developer/references/rust-rules/mem-box-large-variant.md +0 -158
- package/template/agent/skills/rust-developer/references/rust-rules/mem-boxed-slice.md +0 -139
- package/template/agent/skills/rust-developer/references/rust-rules/mem-clone-from.md +0 -147
- package/template/agent/skills/rust-developer/references/rust-rules/mem-compact-string.md +0 -149
- package/template/agent/skills/rust-developer/references/rust-rules/mem-reuse-collections.md +0 -174
- package/template/agent/skills/rust-developer/references/rust-rules/mem-smaller-integers.md +0 -159
- package/template/agent/skills/rust-developer/references/rust-rules/mem-smallvec.md +0 -138
- package/template/agent/skills/rust-developer/references/rust-rules/mem-thinvec.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/mem-with-capacity.md +0 -156
- package/template/agent/skills/rust-developer/references/rust-rules/mem-write-over-format.md +0 -172
- package/template/agent/skills/rust-developer/references/rust-rules/mem-zero-copy.md +0 -164
- package/template/agent/skills/rust-developer/references/rust-rules/name-acronym-word.md +0 -99
- package/template/agent/skills/rust-developer/references/rust-rules/name-as-free.md +0 -104
- package/template/agent/skills/rust-developer/references/rust-rules/name-consts-screaming.md +0 -94
- package/template/agent/skills/rust-developer/references/rust-rules/name-crate-no-rs.md +0 -78
- package/template/agent/skills/rust-developer/references/rust-rules/name-funcs-snake.md +0 -76
- package/template/agent/skills/rust-developer/references/rust-rules/name-into-ownership.md +0 -123
- package/template/agent/skills/rust-developer/references/rust-rules/name-is-has-bool.md +0 -127
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-convention.md +0 -129
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-method.md +0 -131
- package/template/agent/skills/rust-developer/references/rust-rules/name-iter-type-match.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/name-lifetime-short.md +0 -86
- package/template/agent/skills/rust-developer/references/rust-rules/name-no-get-prefix.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/name-to-expensive.md +0 -118
- package/template/agent/skills/rust-developer/references/rust-rules/name-type-param-single.md +0 -92
- package/template/agent/skills/rust-developer/references/rust-rules/name-types-camel.md +0 -65
- package/template/agent/skills/rust-developer/references/rust-rules/name-variants-camel.md +0 -101
- package/template/agent/skills/rust-developer/references/rust-rules/opt-bounds-check.md +0 -161
- package/template/agent/skills/rust-developer/references/rust-rules/opt-cache-friendly.md +0 -187
- package/template/agent/skills/rust-developer/references/rust-rules/opt-codegen-units.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/opt-cold-unlikely.md +0 -152
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-always-rare.md +0 -141
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-never-cold.md +0 -181
- package/template/agent/skills/rust-developer/references/rust-rules/opt-inline-small.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/opt-likely-hint.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/opt-lto-release.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/opt-pgo-profile.md +0 -167
- package/template/agent/skills/rust-developer/references/rust-rules/opt-simd-portable.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/opt-target-cpu.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/own-arc-shared.md +0 -141
- package/template/agent/skills/rust-developer/references/rust-rules/own-borrow-over-clone.md +0 -95
- package/template/agent/skills/rust-developer/references/rust-rules/own-clone-explicit.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/own-copy-small.md +0 -124
- package/template/agent/skills/rust-developer/references/rust-rules/own-cow-conditional.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/own-lifetime-elision.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/own-move-large.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/own-mutex-interior.md +0 -105
- package/template/agent/skills/rust-developer/references/rust-rules/own-rc-single-thread.md +0 -65
- package/template/agent/skills/rust-developer/references/rust-rules/own-refcell-interior.md +0 -97
- package/template/agent/skills/rust-developer/references/rust-rules/own-rwlock-readers.md +0 -122
- package/template/agent/skills/rust-developer/references/rust-rules/own-slice-over-vec.md +0 -119
- package/template/agent/skills/rust-developer/references/rust-rules/perf-black-box-bench.md +0 -153
- package/template/agent/skills/rust-developer/references/rust-rules/perf-chain-avoid.md +0 -136
- package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-into.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/perf-collect-once.md +0 -120
- package/template/agent/skills/rust-developer/references/rust-rules/perf-drain-reuse.md +0 -137
- package/template/agent/skills/rust-developer/references/rust-rules/perf-entry-api.md +0 -134
- package/template/agent/skills/rust-developer/references/rust-rules/perf-extend-batch.md +0 -150
- package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-lazy.md +0 -123
- package/template/agent/skills/rust-developer/references/rust-rules/perf-iter-over-index.md +0 -113
- package/template/agent/skills/rust-developer/references/rust-rules/perf-profile-first.md +0 -175
- package/template/agent/skills/rust-developer/references/rust-rules/perf-release-profile.md +0 -149
- package/template/agent/skills/rust-developer/references/rust-rules/proj-bin-dir.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/proj-flat-small.md +0 -133
- package/template/agent/skills/rust-developer/references/rust-rules/proj-lib-main-split.md +0 -148
- package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-by-feature.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/proj-mod-rs-dir.md +0 -120
- package/template/agent/skills/rust-developer/references/rust-rules/proj-prelude-module.md +0 -155
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-crate-internal.md +0 -139
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-super-parent.md +0 -135
- package/template/agent/skills/rust-developer/references/rust-rules/proj-pub-use-reexport.md +0 -162
- package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-deps.md +0 -186
- package/template/agent/skills/rust-developer/references/rust-rules/proj-workspace-large.md +0 -162
- package/template/agent/skills/rust-developer/references/rust-rules/test-arrange-act-assert.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/test-cfg-test-module.md +0 -151
- package/template/agent/skills/rust-developer/references/rust-rules/test-criterion-bench.md +0 -171
- package/template/agent/skills/rust-developer/references/rust-rules/test-descriptive-names.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/test-doctest-examples.md +0 -168
- package/template/agent/skills/rust-developer/references/rust-rules/test-fixture-raii.md +0 -151
- package/template/agent/skills/rust-developer/references/rust-rules/test-integration-dir.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/test-mock-traits.md +0 -189
- package/template/agent/skills/rust-developer/references/rust-rules/test-mockall-mocking.md +0 -226
- package/template/agent/skills/rust-developer/references/rust-rules/test-proptest-properties.md +0 -161
- package/template/agent/skills/rust-developer/references/rust-rules/test-should-panic.md +0 -130
- package/template/agent/skills/rust-developer/references/rust-rules/test-tokio-async.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/test-use-super.md +0 -127
- package/template/agent/skills/rust-developer/references/rust-rules/type-enum-states.md +0 -154
- package/template/agent/skills/rust-developer/references/rust-rules/type-generic-bounds.md +0 -142
- package/template/agent/skills/rust-developer/references/rust-rules/type-never-diverge.md +0 -146
- package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-ids.md +0 -160
- package/template/agent/skills/rust-developer/references/rust-rules/type-newtype-validated.md +0 -159
- package/template/agent/skills/rust-developer/references/rust-rules/type-no-stringly.md +0 -144
- package/template/agent/skills/rust-developer/references/rust-rules/type-option-nullable.md +0 -137
- package/template/agent/skills/rust-developer/references/rust-rules/type-phantom-marker.md +0 -188
- package/template/agent/skills/rust-developer/references/rust-rules/type-repr-transparent.md +0 -143
- package/template/agent/skills/rust-developer/references/rust-rules/type-result-fallible.md +0 -131
- package/template/agent/skills/saas-architect/SKILL.md +0 -139
- package/template/agent/skills/security-engineer/SKILL.md +0 -133
- package/template/agent/skills/seo-specialist/SKILL.md +0 -130
- package/template/agent/skills/solo-founder-ops/SKILL.md +0 -56
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
# doc-safety-section
|
|
2
|
-
|
|
3
|
-
> Include `# Safety` section for unsafe functions
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
Unsafe functions require callers to uphold invariants that the compiler cannot verify. The `# Safety` section documents exactly what the caller must guarantee for the function to be sound. Without this, users cannot safely call the function.
|
|
8
|
-
|
|
9
|
-
This is not optional—it's a requirement for sound unsafe code.
|
|
10
|
-
|
|
11
|
-
## Bad
|
|
12
|
-
|
|
13
|
-
```rust
|
|
14
|
-
/// Reads a value from a raw pointer.
|
|
15
|
-
pub unsafe fn read_ptr<T>(ptr: *const T) -> T {
|
|
16
|
-
// What guarantees must the caller provide? Unknown!
|
|
17
|
-
ptr.read()
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/// Creates a string from raw parts.
|
|
21
|
-
pub unsafe fn string_from_raw(ptr: *mut u8, len: usize, cap: usize) -> String {
|
|
22
|
-
String::from_raw_parts(ptr, len, cap)
|
|
23
|
-
}
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Good
|
|
27
|
-
|
|
28
|
-
```rust
|
|
29
|
-
/// Reads a value from a raw pointer.
|
|
30
|
-
///
|
|
31
|
-
/// # Safety
|
|
32
|
-
///
|
|
33
|
-
/// The caller must ensure that:
|
|
34
|
-
/// - `ptr` is valid for reads of `size_of::<T>()` bytes
|
|
35
|
-
/// - `ptr` is properly aligned for type `T`
|
|
36
|
-
/// - `ptr` points to a properly initialized value of type `T`
|
|
37
|
-
/// - The memory referenced by `ptr` is not mutated during this call
|
|
38
|
-
pub unsafe fn read_ptr<T>(ptr: *const T) -> T {
|
|
39
|
-
ptr.read()
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/// Creates a `String` from raw parts.
|
|
43
|
-
///
|
|
44
|
-
/// # Safety
|
|
45
|
-
///
|
|
46
|
-
/// The caller must guarantee that:
|
|
47
|
-
/// - `ptr` was allocated by the same allocator that `String` uses
|
|
48
|
-
/// - `len` is less than or equal to `cap`
|
|
49
|
-
/// - The first `len` bytes at `ptr` are valid UTF-8
|
|
50
|
-
/// - `cap` is the capacity that `ptr` was allocated with
|
|
51
|
-
/// - No other code will use `ptr` after this call (ownership is transferred)
|
|
52
|
-
///
|
|
53
|
-
/// Violating these requirements leads to undefined behavior including
|
|
54
|
-
/// memory corruption, use-after-free, or invalid UTF-8 in strings.
|
|
55
|
-
pub unsafe fn string_from_raw(ptr: *mut u8, len: usize, cap: usize) -> String {
|
|
56
|
-
String::from_raw_parts(ptr, len, cap)
|
|
57
|
-
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## Key Elements of Safety Documentation
|
|
61
|
-
|
|
62
|
-
| Element | Description |
|
|
63
|
-
|---------|-------------|
|
|
64
|
-
| **Preconditions** | What must be true before calling |
|
|
65
|
-
| **Pointer validity** | Alignment, null-ness, lifetime |
|
|
66
|
-
| **Memory ownership** | Who owns what, transfer semantics |
|
|
67
|
-
| **Invariants** | Type invariants that must hold |
|
|
68
|
-
| **Consequences** | What happens if violated |
|
|
69
|
-
|
|
70
|
-
## Pattern: Unsafe Trait Implementations
|
|
71
|
-
|
|
72
|
-
```rust
|
|
73
|
-
/// A type that can be safely zeroed.
|
|
74
|
-
///
|
|
75
|
-
/// # Safety
|
|
76
|
-
///
|
|
77
|
-
/// Implementing this trait guarantees that:
|
|
78
|
-
/// - All bit patterns of zeros represent a valid value of this type
|
|
79
|
-
/// - The type has no padding bytes that could leak data
|
|
80
|
-
/// - The type contains no references or pointers
|
|
81
|
-
pub unsafe trait Zeroable {
|
|
82
|
-
fn zeroed() -> Self;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// SAFETY: u32 is a primitive integer type where all zero bits
|
|
86
|
-
// represent a valid value (0).
|
|
87
|
-
unsafe impl Zeroable for u32 {
|
|
88
|
-
fn zeroed() -> Self {
|
|
89
|
-
0
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Pattern: Unsafe Blocks in Safe Functions
|
|
95
|
-
|
|
96
|
-
When a safe function contains unsafe blocks, document the invariants:
|
|
97
|
-
|
|
98
|
-
```rust
|
|
99
|
-
/// Returns a reference to the element at the given index.
|
|
100
|
-
///
|
|
101
|
-
/// Returns `None` if the index is out of bounds.
|
|
102
|
-
pub fn get(&self, index: usize) -> Option<&T> {
|
|
103
|
-
if index < self.len {
|
|
104
|
-
// SAFETY: We just verified that index < len, so this
|
|
105
|
-
// access is within bounds.
|
|
106
|
-
Some(unsafe { self.data.get_unchecked(index) })
|
|
107
|
-
} else {
|
|
108
|
-
None
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## Common Safety Requirements
|
|
114
|
-
|
|
115
|
-
```rust
|
|
116
|
-
/// # Safety
|
|
117
|
-
///
|
|
118
|
-
/// - Pointer must be non-null
|
|
119
|
-
/// - Pointer must be aligned to `align_of::<T>()`
|
|
120
|
-
/// - Pointer must be valid for reads/writes of `size_of::<T>()` bytes
|
|
121
|
-
/// - Pointer must point to an initialized value of `T`
|
|
122
|
-
/// - The referenced memory must not be accessed through any other pointer
|
|
123
|
-
/// for the duration of the returned reference
|
|
124
|
-
/// - The total size must not exceed `isize::MAX`
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## See Also
|
|
128
|
-
|
|
129
|
-
- [doc-panics-section](./doc-panics-section.md) - Documenting panics
|
|
130
|
-
- [lint-unsafe-doc](./lint-unsafe-doc.md) - Enforcing unsafe documentation
|
|
131
|
-
- [doc-errors-section](./doc-errors-section.md) - Documenting errors
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
# err-anyhow-app
|
|
2
|
-
|
|
3
|
-
> Use `anyhow` for application error handling
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
Applications often don't need typed errors - they just need to report what went wrong with good context. `anyhow` provides easy error handling with context chaining, backtraces, and conversion from any error type.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// Tedious type management
|
|
13
|
-
fn load_config() -> Result<Config, Box<dyn std::error::Error>> {
|
|
14
|
-
let path = find_config()?; // Returns FindError
|
|
15
|
-
let content = std::fs::read_to_string(&path)?; // Returns io::Error
|
|
16
|
-
let config: Config = toml::from_str(&content)?; // Returns toml::Error
|
|
17
|
-
validate(&config)?; // Returns ValidationError
|
|
18
|
-
Ok(config)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// No context - hard to debug
|
|
22
|
-
fn process() -> Result<(), Box<dyn std::error::Error>> {
|
|
23
|
-
let data = fetch()?; // Which fetch failed?
|
|
24
|
-
transform(data)?; // What was being transformed?
|
|
25
|
-
save()?; // Where was it saving to?
|
|
26
|
-
Ok(())
|
|
27
|
-
}
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Good
|
|
31
|
-
|
|
32
|
-
```rust
|
|
33
|
-
use anyhow::{Context, Result};
|
|
34
|
-
|
|
35
|
-
fn load_config() -> Result<Config> {
|
|
36
|
-
let path = find_config()
|
|
37
|
-
.context("failed to locate config file")?;
|
|
38
|
-
|
|
39
|
-
let content = std::fs::read_to_string(&path)
|
|
40
|
-
.with_context(|| format!("failed to read config from {}", path.display()))?;
|
|
41
|
-
|
|
42
|
-
let config: Config = toml::from_str(&content)
|
|
43
|
-
.context("failed to parse config as TOML")?;
|
|
44
|
-
|
|
45
|
-
validate(&config)
|
|
46
|
-
.context("config validation failed")?;
|
|
47
|
-
|
|
48
|
-
Ok(config)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Error message: "config validation failed: field 'port' must be > 0"
|
|
52
|
-
// Full chain preserved for debugging
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Key Features
|
|
56
|
-
|
|
57
|
-
```rust
|
|
58
|
-
use anyhow::{anyhow, bail, ensure, Context, Result};
|
|
59
|
-
|
|
60
|
-
fn example() -> Result<()> {
|
|
61
|
-
// Create ad-hoc errors
|
|
62
|
-
let err = anyhow!("something went wrong");
|
|
63
|
-
|
|
64
|
-
// Early return with error
|
|
65
|
-
bail!("aborting due to {}", reason);
|
|
66
|
-
|
|
67
|
-
// Assert with error
|
|
68
|
-
ensure!(condition, "condition was false");
|
|
69
|
-
|
|
70
|
-
// Add context to any error
|
|
71
|
-
risky_operation()
|
|
72
|
-
.context("risky operation failed")?;
|
|
73
|
-
|
|
74
|
-
// Dynamic context
|
|
75
|
-
fetch(url)
|
|
76
|
-
.with_context(|| format!("failed to fetch {}", url))?;
|
|
77
|
-
|
|
78
|
-
Ok(())
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## Main Function Pattern
|
|
83
|
-
|
|
84
|
-
```rust
|
|
85
|
-
use anyhow::Result;
|
|
86
|
-
|
|
87
|
-
fn main() -> Result<()> {
|
|
88
|
-
let config = load_config()?;
|
|
89
|
-
run_app(config)?;
|
|
90
|
-
Ok(())
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Or with custom exit handling
|
|
94
|
-
fn main() {
|
|
95
|
-
if let Err(e) = run() {
|
|
96
|
-
eprintln!("Error: {:#}", e); // Pretty-print with causes
|
|
97
|
-
std::process::exit(1);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
fn run() -> Result<()> {
|
|
102
|
-
// Application logic
|
|
103
|
-
Ok(())
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## Error Display Formats
|
|
108
|
-
|
|
109
|
-
```rust
|
|
110
|
-
use anyhow::Result;
|
|
111
|
-
|
|
112
|
-
fn show_error(err: anyhow::Error) {
|
|
113
|
-
// Just the top-level message
|
|
114
|
-
println!("{}", err);
|
|
115
|
-
// "config validation failed"
|
|
116
|
-
|
|
117
|
-
// With cause chain (# alternate format)
|
|
118
|
-
println!("{:#}", err);
|
|
119
|
-
// "config validation failed: field 'port' must be > 0"
|
|
120
|
-
|
|
121
|
-
// Debug format with backtrace
|
|
122
|
-
println!("{:?}", err);
|
|
123
|
-
// Full backtrace if RUST_BACKTRACE=1
|
|
124
|
-
|
|
125
|
-
// Iterate through cause chain
|
|
126
|
-
for cause in err.chain() {
|
|
127
|
-
println!("Caused by: {}", cause);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## Combining with thiserror
|
|
133
|
-
|
|
134
|
-
```rust
|
|
135
|
-
// In your library crate - typed errors
|
|
136
|
-
use thiserror::Error;
|
|
137
|
-
|
|
138
|
-
#[derive(Error, Debug)]
|
|
139
|
-
pub enum ApiError {
|
|
140
|
-
#[error("rate limited")]
|
|
141
|
-
RateLimited,
|
|
142
|
-
#[error("not found: {0}")]
|
|
143
|
-
NotFound(String),
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// In your application - anyhow for handling
|
|
147
|
-
use anyhow::{Context, Result};
|
|
148
|
-
|
|
149
|
-
fn fetch_user(id: u64) -> Result<User> {
|
|
150
|
-
api::get_user(id)
|
|
151
|
-
.with_context(|| format!("failed to fetch user {}", id))
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Can still downcast if needed
|
|
155
|
-
fn handle_error(err: anyhow::Error) {
|
|
156
|
-
if let Some(api_err) = err.downcast_ref::<ApiError>() {
|
|
157
|
-
match api_err {
|
|
158
|
-
ApiError::RateLimited => wait_and_retry(),
|
|
159
|
-
ApiError::NotFound(id) => log_missing(id),
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## When to Use Which
|
|
166
|
-
|
|
167
|
-
| Situation | Use |
|
|
168
|
-
|-----------|-----|
|
|
169
|
-
| Library public API | `thiserror` |
|
|
170
|
-
| Application code | `anyhow` |
|
|
171
|
-
| CLI tools | `anyhow` |
|
|
172
|
-
| Internal library code | Either |
|
|
173
|
-
| Need to match error variants | `thiserror` |
|
|
174
|
-
| Just need to report errors | `anyhow` |
|
|
175
|
-
|
|
176
|
-
## See Also
|
|
177
|
-
|
|
178
|
-
- [err-thiserror-lib](err-thiserror-lib.md) - Use thiserror for libraries
|
|
179
|
-
- [err-context-chain](err-context-chain.md) - Add context to errors
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
# err-context-chain
|
|
2
|
-
|
|
3
|
-
> Add context with `.context()` or `.with_context()`
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
Raw errors often lack information about what operation failed. Adding context creates an error chain that tells the full story: what you were trying to do, and why it failed.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// Raw error - no context
|
|
13
|
-
fn load_user(id: u64) -> Result<User, Error> {
|
|
14
|
-
let path = format!("users/{}.json", id);
|
|
15
|
-
let content = std::fs::read_to_string(&path)?;
|
|
16
|
-
Ok(serde_json::from_str(&content)?)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// Error message: "No such file or directory (os error 2)"
|
|
20
|
-
// Which file? What were we doing?
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Good
|
|
24
|
-
|
|
25
|
-
```rust
|
|
26
|
-
use anyhow::{Context, Result};
|
|
27
|
-
|
|
28
|
-
fn load_user(id: u64) -> Result<User> {
|
|
29
|
-
let path = format!("users/{}.json", id);
|
|
30
|
-
|
|
31
|
-
let content = std::fs::read_to_string(&path)
|
|
32
|
-
.with_context(|| format!("failed to read user file: {}", path))?;
|
|
33
|
-
|
|
34
|
-
let user: User = serde_json::from_str(&content)
|
|
35
|
-
.with_context(|| format!("failed to parse user {} JSON", id))?;
|
|
36
|
-
|
|
37
|
-
Ok(user)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// Error: "failed to parse user 42 JSON"
|
|
41
|
-
// Caused by: "expected ':' at line 5 column 12"
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## context() vs with_context()
|
|
45
|
-
|
|
46
|
-
```rust
|
|
47
|
-
// context() - static string (slight allocation)
|
|
48
|
-
fs::read_to_string(path)
|
|
49
|
-
.context("failed to read config")?;
|
|
50
|
-
|
|
51
|
-
// with_context() - lazy evaluation (only allocates on error)
|
|
52
|
-
fs::read_to_string(path)
|
|
53
|
-
.with_context(|| format!("failed to read {}", path))?;
|
|
54
|
-
|
|
55
|
-
// Use with_context() when:
|
|
56
|
-
// - Message includes runtime data (format!)
|
|
57
|
-
// - Computing the message is expensive
|
|
58
|
-
// - Error path is cold (most of the time)
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Building Context Chains
|
|
62
|
-
|
|
63
|
-
```rust
|
|
64
|
-
fn process_order(order_id: u64) -> Result<()> {
|
|
65
|
-
let order = fetch_order(order_id)
|
|
66
|
-
.with_context(|| format!("failed to fetch order {}", order_id))?;
|
|
67
|
-
|
|
68
|
-
let user = load_user(order.user_id)
|
|
69
|
-
.with_context(|| format!("failed to load user for order {}", order_id))?;
|
|
70
|
-
|
|
71
|
-
let payment = process_payment(&order, &user)
|
|
72
|
-
.context("payment processing failed")?;
|
|
73
|
-
|
|
74
|
-
ship_order(&order, &payment)
|
|
75
|
-
.context("shipping failed")?;
|
|
76
|
-
|
|
77
|
-
Ok(())
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Full error chain:
|
|
81
|
-
// "shipping failed"
|
|
82
|
-
// Caused by: "carrier API returned 503"
|
|
83
|
-
// Caused by: "connection refused"
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## Displaying Error Chains
|
|
87
|
-
|
|
88
|
-
```rust
|
|
89
|
-
fn main() {
|
|
90
|
-
if let Err(e) = run() {
|
|
91
|
-
// Just top-level message
|
|
92
|
-
eprintln!("Error: {}", e);
|
|
93
|
-
|
|
94
|
-
// Full chain with alternate format
|
|
95
|
-
eprintln!("Error: {:#}", e);
|
|
96
|
-
|
|
97
|
-
// Debug format (includes backtrace if enabled)
|
|
98
|
-
eprintln!("Error: {:?}", e);
|
|
99
|
-
|
|
100
|
-
// Iterate through chain
|
|
101
|
-
for (i, cause) in e.chain().enumerate() {
|
|
102
|
-
eprintln!(" {}: {}", i, cause);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## With thiserror
|
|
109
|
-
|
|
110
|
-
```rust
|
|
111
|
-
use thiserror::Error;
|
|
112
|
-
|
|
113
|
-
#[derive(Error, Debug)]
|
|
114
|
-
pub enum AppError {
|
|
115
|
-
#[error("failed to load config from {path}")]
|
|
116
|
-
ConfigLoad {
|
|
117
|
-
path: String,
|
|
118
|
-
#[source]
|
|
119
|
-
cause: std::io::Error,
|
|
120
|
-
},
|
|
121
|
-
|
|
122
|
-
#[error("failed to connect to database")]
|
|
123
|
-
Database {
|
|
124
|
-
#[source]
|
|
125
|
-
cause: sqlx::Error,
|
|
126
|
-
},
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Usage
|
|
130
|
-
fn load_config(path: &str) -> Result<Config, AppError> {
|
|
131
|
-
let content = std::fs::read_to_string(path)
|
|
132
|
-
.map_err(|e| AppError::ConfigLoad {
|
|
133
|
-
path: path.to_string(),
|
|
134
|
-
cause: e,
|
|
135
|
-
})?;
|
|
136
|
-
// ...
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
## See Also
|
|
141
|
-
|
|
142
|
-
- [err-anyhow-app](err-anyhow-app.md) - Use anyhow for applications
|
|
143
|
-
- [err-source-chain](err-source-chain.md) - Use #[source] to chain errors
|
|
144
|
-
- [err-question-mark](err-question-mark.md) - Use ? for propagation
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
# err-custom-type
|
|
2
|
-
|
|
3
|
-
> Define custom error types for domain-specific failures
|
|
4
|
-
|
|
5
|
-
## Why It Matters
|
|
6
|
-
|
|
7
|
-
Generic errors like `String`, `Box<dyn Error>`, or catch-all enums obscure what can actually go wrong. Custom error types document failure modes in the type system, enable pattern matching for specific handling, and provide clear API contracts. They make your code self-documenting and help callers handle errors appropriately.
|
|
8
|
-
|
|
9
|
-
## Bad
|
|
10
|
-
|
|
11
|
-
```rust
|
|
12
|
-
// Generic string errors - no structure
|
|
13
|
-
fn validate_user(user: &User) -> Result<(), String> {
|
|
14
|
-
if user.name.is_empty() {
|
|
15
|
-
return Err("Name is empty".to_string());
|
|
16
|
-
}
|
|
17
|
-
if user.age > 150 {
|
|
18
|
-
return Err("Age is invalid".to_string());
|
|
19
|
-
}
|
|
20
|
-
Ok(())
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Caller can't match on specific errors
|
|
24
|
-
match validate_user(&user) {
|
|
25
|
-
Ok(()) => save(user),
|
|
26
|
-
Err(msg) => {
|
|
27
|
-
// Can only do string comparison - fragile!
|
|
28
|
-
if msg.contains("Name") {
|
|
29
|
-
prompt_for_name()
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Good
|
|
36
|
-
|
|
37
|
-
```rust
|
|
38
|
-
use thiserror::Error;
|
|
39
|
-
|
|
40
|
-
#[derive(Error, Debug)]
|
|
41
|
-
pub enum ValidationError {
|
|
42
|
-
#[error("name cannot be empty")]
|
|
43
|
-
EmptyName,
|
|
44
|
-
|
|
45
|
-
#[error("name exceeds maximum length of {max} characters")]
|
|
46
|
-
NameTooLong { max: usize, actual: usize },
|
|
47
|
-
|
|
48
|
-
#[error("invalid age {0}: must be between 0 and 150")]
|
|
49
|
-
InvalidAge(u8),
|
|
50
|
-
|
|
51
|
-
#[error("email format is invalid: {0}")]
|
|
52
|
-
InvalidEmail(String),
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
fn validate_user(user: &User) -> Result<(), ValidationError> {
|
|
56
|
-
if user.name.is_empty() {
|
|
57
|
-
return Err(ValidationError::EmptyName);
|
|
58
|
-
}
|
|
59
|
-
if user.name.len() > 100 {
|
|
60
|
-
return Err(ValidationError::NameTooLong {
|
|
61
|
-
max: 100,
|
|
62
|
-
actual: user.name.len()
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
if user.age > 150 {
|
|
66
|
-
return Err(ValidationError::InvalidAge(user.age));
|
|
67
|
-
}
|
|
68
|
-
Ok(())
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Caller can match specifically
|
|
72
|
-
match validate_user(&user) {
|
|
73
|
-
Ok(()) => save(user),
|
|
74
|
-
Err(ValidationError::EmptyName) => prompt_for_name(),
|
|
75
|
-
Err(ValidationError::InvalidAge(age)) => {
|
|
76
|
-
show_error(&format!("Please enter a valid age (you entered {})", age))
|
|
77
|
-
}
|
|
78
|
-
Err(e) => show_error(&e.to_string()),
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## Error Type Design Guidelines
|
|
83
|
-
|
|
84
|
-
```rust
|
|
85
|
-
// 1. Group related errors in domain-specific enums
|
|
86
|
-
#[derive(Error, Debug)]
|
|
87
|
-
pub enum AuthError {
|
|
88
|
-
#[error("invalid credentials")]
|
|
89
|
-
InvalidCredentials,
|
|
90
|
-
#[error("account locked after {attempts} failed attempts")]
|
|
91
|
-
AccountLocked { attempts: u32 },
|
|
92
|
-
#[error("token expired")]
|
|
93
|
-
TokenExpired,
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
#[derive(Error, Debug)]
|
|
97
|
-
pub enum PaymentError {
|
|
98
|
-
#[error("insufficient funds: need {required}, have {available}")]
|
|
99
|
-
InsufficientFunds { required: Decimal, available: Decimal },
|
|
100
|
-
#[error("card declined: {reason}")]
|
|
101
|
-
CardDeclined { reason: String },
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// 2. Include relevant data for error handling/display
|
|
105
|
-
#[derive(Error, Debug)]
|
|
106
|
-
pub enum FileError {
|
|
107
|
-
#[error("file not found: {path}")]
|
|
108
|
-
NotFound { path: PathBuf },
|
|
109
|
-
#[error("permission denied for {path}")]
|
|
110
|
-
PermissionDenied { path: PathBuf },
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// 3. Consider #[non_exhaustive] for public APIs
|
|
114
|
-
#[derive(Error, Debug)]
|
|
115
|
-
#[non_exhaustive] // Allows adding variants without breaking changes
|
|
116
|
-
pub enum ApiError {
|
|
117
|
-
#[error("rate limited")]
|
|
118
|
-
RateLimited,
|
|
119
|
-
#[error("not found")]
|
|
120
|
-
NotFound,
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## When to Use What
|
|
125
|
-
|
|
126
|
-
| Error Pattern | Use Case |
|
|
127
|
-
|---------------|----------|
|
|
128
|
-
| Custom enum | Library with specific failure modes |
|
|
129
|
-
| `thiserror` | Libraries needing `std::error::Error` |
|
|
130
|
-
| `anyhow::Error` | Applications, prototypes |
|
|
131
|
-
| Struct with source | Single error type with wrapped cause |
|
|
132
|
-
|
|
133
|
-
## Struct-Based Errors
|
|
134
|
-
|
|
135
|
-
For single error types with rich context:
|
|
136
|
-
|
|
137
|
-
```rust
|
|
138
|
-
#[derive(Error, Debug)]
|
|
139
|
-
#[error("query failed for table '{table}' with filter '{filter}'")]
|
|
140
|
-
pub struct QueryError {
|
|
141
|
-
pub table: String,
|
|
142
|
-
pub filter: String,
|
|
143
|
-
#[source]
|
|
144
|
-
pub source: DatabaseError,
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## See Also
|
|
149
|
-
|
|
150
|
-
- [err-thiserror-lib](./err-thiserror-lib.md) - thiserror for error definitions
|
|
151
|
-
- [err-anyhow-app](./err-anyhow-app.md) - When to use anyhow instead
|
|
152
|
-
- [api-non-exhaustive](./api-non-exhaustive.md) - Forward-compatible enums
|