1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2026 Pierre Gronau, ndaal in Cologne
//! Compile-time invariants for `csaf-core`, per `skills/rust-static-assertions`.
//!
//! Every assertion here fails the **build**, not a test run. That is the whole
//! point: these are properties a runtime test cannot catch reliably, because
//! by the time you notice them at runtime the damage is a deadlock, a data
//! race, or a type that silently stopped crossing an `.await`.
//!
//! Concretely, each block below guards against a specific regression that a
//! well-meaning refactor could introduce without any test going red:
//!
//! - A handle shared across the tokio runtime silently losing `Send`/`Sync`
//! because someone swapped an `Arc<Mutex<_>>` for an `Rc<RefCell<_>>`.
//! - An error type ceasing to be `Send + Sync + 'static`, so it can no longer
//! be boxed into `anyhow::Error` or returned from a spawned task — which
//! surfaces as an unrelated, confusing compile error somewhere else.
//! - A trait losing object-safety, breaking `Arc<dyn Trait>` injection (the
//! transport seam the whole offline updater suite depends on).
//! - An enum growing an unexpectedly large variant, quietly inflating every
//! `Result<_, E>` in the crate.
use ;
// ---------------------------------------------------------------------------
// 1. Handles shared across the async runtime must stay Send + Sync
// ---------------------------------------------------------------------------
// `CsafStorage` is opened once in `main` and read from concurrent request
// handlers. If it stops being `Sync`, every handler that touches it stops
// compiling — but only after someone has already restructured the storage
// layer. Fail here instead, at the point of the change.
assert_impl_all!;
// `AppConfig` is cloned into background tasks and read from handlers.
assert_impl_all!;
// The SQLite pool is handed to blocking tasks via `spawn_blocking`, which
// requires `Send + 'static`.
assert_impl_all!;
// ---------------------------------------------------------------------------
// 2. The error-type contract
// ---------------------------------------------------------------------------
// Errors cross `.await` points and task boundaries and get boxed into
// `anyhow::Error`, which requires `Error + Send + Sync + 'static`. Losing any
// one of these is the classic "why does this no longer compile three modules
// away" regression.
assert_impl_all!;
// The updater's error is returned from `perform` and rendered by both
// binaries' CLI dispatch, so it carries the same contract.
assert_impl_all!;
// ---------------------------------------------------------------------------
// 3. Object-safety of the injected transport
// ---------------------------------------------------------------------------
// The entire offline self-update test suite injects `Arc<dyn HttpClient>`.
// If this trait ever stops being object-safe (a generic method, a `Self`
// return), the seam disappears and the tests silently fall back to hitting
// the real network — or stop compiling in a way that invites "just delete
// the test". Pin it.
assert_obj_safe!;
assert_obj_safe!;
// ---------------------------------------------------------------------------
// 4. Update outcomes stay cheap, comparable and inspectable
// ---------------------------------------------------------------------------
// `UpdateOutcome` is compared in tests and matched in both binaries.
assert_impl_all!;
// `UpdateFlags` is passed by value through the CLI dispatch of both binaries;
// `Copy` is what keeps that free and prevents an accidental clone-per-flag.
assert_impl_all!;
// The three flag fields ARE the CLI contract. Renaming one silently breaks
// the shared dispatch for whichever binary was not updated in the same
// commit, so pin the names at compile time.
assert_fields!;