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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//! Where every `#[skyzen::openapi]` handler's metadata is collected, and the only place in the
//! crate that asks what target it is building for.
//!
//! Two backends, chosen by target, because they do not cost the same:
//!
//! - **Native uses [`linkme`], and pays nothing.** A [`HandlerSpec`] is a `static` placed in a
//! dedicated linker section; the linker lays the section out, no code runs before `main`, and
//! reading the registry is reading a slice. Registration is free at runtime and the specs of
//! handlers nothing routes are still just data the linker already had to place.
//! - **wasm32 uses [`inventory`], and pays for it.** `linkme` has no WebAssembly backend — its
//! supported-platform table is Linux, macOS, Windows, FreeBSD, OpenBSD and illumos — so the edge
//! has to fall back on life-before-main constructors, one per documented handler, each pushing
//! onto a linked list when the module initializes. That is real startup work and real code size,
//! which is why it is confined here rather than adopted everywhere: an isolate's cold start
//! absorbs a handful of pointer pushes, and the alternative on the edge is having no document at
//! all.
//!
//! **The public surface is identical on every target**: [`iter`], and
//! [`__register_handler_spec!`](crate::__register_handler_spec) with one invocation shape. Which
//! backend answers is a private matter of this file — the `#[skyzen::openapi]` expansion, the rest
//! of the crate and an application's own code all name the same items whatever they compile for.
use ;
/// Every handler specification this binary registered, in no particular order.
/// The identity `#[skyzen::main]` registered for this binary, if it was built with one.
///
/// This is how a document learns whose it is without anybody passing it along. Skyzen cannot read
/// `CARGO_PKG_NAME` on an application's behalf — `env!` expands where it is *written*, so asking
/// inside skyzen names skyzen — but `#[skyzen::main]` expands in the application's crate, where
/// the answer is right, and registers it here exactly as `#[skyzen::openapi]` registers a handler.
///
/// One per binary, because `#[skyzen::main]` defines the entry point and there is only one of
/// those. `None` for a library under test, or an application that embeds skyzen behind its own
/// runtime; both can still name themselves with [`OpenApi::with_info`](super::OpenApi::with_info).
/// The chosen backend's plumbing.
///
/// Public because [`__register_handler_spec!`](crate::__register_handler_spec) expands in the
/// application's crate and has to name it from there, and hidden because naming it from anywhere
/// else is a mistake: these are the two items that genuinely differ by target, and keeping them
/// behind one door is what lets everything above be the same everywhere.
/// Register one handler's specification with the registry.
///
/// Called only from the `#[skyzen::openapi]` expansion, which builds the [`HandlerSpec`] and knows
/// nothing about how it is stored.
///
/// Defined twice, once per target, rather than once emitting `#[cfg]`-guarded code: the two
/// backends want genuinely different item shapes — a named `static` carrying attributes for
/// `linkme`, a bare expression for `inventory` — and choosing here means the *caller* sees one
/// macro with one invocation shape, and the code it expands to carries no `#[cfg]` of its own.
/// Register one handler's specification with the registry.
///
/// See the native definition above; this is the same macro for the target whose registry is
/// `inventory`, and takes the same arguments. The identifier is unused here — `inventory` names
/// its own shim — and is accepted so that one invocation compiles for both.
/// Register this binary's identity, so a document can be titled without anybody passing a name
/// down through the routing API.
///
/// Emitted once by `#[skyzen::main]`, in the application's crate, where `env!("CARGO_PKG_NAME")`
/// reads the application rather than skyzen.
/// Register this binary's identity. See the native definition above; same arguments, same one
/// invocation, for the target whose registry is `inventory`.