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
use ;
use HashMap;
/// Values a migration step needs that are not in the store.
///
/// A step is a plain `fn(&mut MigrationContext)` collected at link time, so it
/// captures nothing: anything it needs from the application - a lookup table,
/// a client, the old config it is porting away from - has nowhere to arrive
/// except a global. This is that argument, handed over at
/// [`StoreBuilder::provide`](crate::StoreBuilder::provide) and read back by
/// type.
///
/// Keyed by [`TypeId`], so one value of each type. A step wanting two of the
/// same thing wraps them in a type that says which is which, which is also
/// what makes the call site legible.
///
/// Nothing here is `Send` or `Sync`, and deliberately. A GUI has plenty worth
/// handing a migration that is neither - an `Rc`, a `RefCell`, a handle its
/// toolkit refuses to move - and a value put here is only ever borrowed by
/// the step and dropped with the set, so a bound demanding otherwise would
/// rule those out to buy nothing.
///
/// The safety of that is the compiler's, not an assumption about where
/// migrations run. `MigrationContext` and `MigrationSet` are both public, so
/// a caller can drive a migration themselves rather than through
/// `StoreBuilder`, and "it happens on the thread that opened the store" is a
/// fact about today's engine rather than something to hang a bound on. What
/// holds regardless is that a `Provided` cannot reach another thread at all.
///
/// The cost, plainly: `Box<dyn Any>` erases auto traits instead of
/// propagating them, so `StoreBuilder` stops being `Send` once anything is
/// provided - even something that was `Send` itself.
/// The value, and the name of its type - which `Any` erases and `TypeId`
/// cannot give back, so it is kept here rather than lost. A step asking for
/// something absent is an error path, and an error that can list what *is*
/// here is worth the one `&'static str`.