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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
//! Type-erased capability entries.
//!
//! Two families:
//!
//! - **Registry entries** ([`LocalCapabilityEntry`], [`SharedCapabilityEntry`]):
//! what [`CapabilityRegistry`](super::CapabilityRegistry) stores per
//! `(capability, extension)` registration. Each owns a produce
//! closure minted by the `#[capability]`-generated caster
//! (`shared_entry::<E>` / `local_entry::<E>`) which internally calls
//! the extension's instance factory, downcasts to the concrete
//! extension type, and coerces to the capability's trait object.
//! - **Resolved entries** ([`ResolvedLocalEntry`], [`ResolvedSharedEntry`]):
//! what [`resolve_bindings`](super::resolve_bindings) produces per
//! node, each holding a cloned produce closure and a shared
//! consumption cell.
use ExtensionId;
use Any;
use Cell;
use Rc;
// -- Cloneable produce closures ----------------------------------------------
//
// `Box<dyn Fn>` is not `Clone`, so we thread cloning through an
// object-safe `clone_box` method. One extension may provide multiple
// capabilities; each capability needs its own produce closure, and
// `resolve_bindings` hands per-node entries their own copy.
/// Object-safe `Fn + Clone` producing an erased shared trait object.
///
/// The stored closure returns `Box<Box<dyn C::Shared>>` erased as
/// `Box<dyn Any + Send>` -- the double-box envelope the registry uses.
/// The envelope is only moved through the build-time registry; the
/// contained `C::Shared` trait object is `Send + Sync`.
/// Object-safe `Fn + Clone` producing an erased local trait object.
///
/// The stored closure returns `Box<Box<dyn C::Local>>` erased as
/// `Box<dyn Any>` -- the double-box envelope the registry uses,
/// mirroring the shared-side shape (without the `Send` bound).
// -- Registry entries --------------------------------------------------------
/// A type-erased local (!Send) capability entry.
///
/// The `produce` closure -- built by the `#[capability]`-generated
/// `local_entry::<E>` caster -- mints a fresh `Box<dyn C::Local>` by
/// calling the extension's `LocalInstanceFactory`, downcasting to `E`,
/// and coercing to the trait object.
/// A type-erased shared (Send + Sync) capability entry.
///
/// Two closures/fn pointers, both minted by the
/// `#[capability]`-generated `shared_entry::<E>` caster:
///
/// - `produce` -- builds `Box<Box<dyn C::Shared>>` erased as
/// `Box<dyn Any + Send>`. The envelope is moved, not shared; the
/// contained capability object is `Send + Sync`. Called per consumer.
/// - `adapt_as_local` -- takes that same erased double box and returns
/// `Box<Box<dyn C::Local>>` erased as `Box<dyn Any>`. Used by the
/// `SharedAsLocal` fallback path in `resolve_bindings`.
// -- Resolved entries (per-node) ---------------------------------------------
/// A resolved local capability entry for a specific node.
///
/// Inserted only for **native** local registrations. The
/// SharedAsLocal fallback path does *not* produce a separate local
/// entry -- instead, [`Capabilities::require_local`] falls through to
/// the [`ResolvedSharedEntry`] when no native local entry exists,
/// taking the shared `produce` cell and routing its output through
/// the entry's `adapt_as_local` fn pointer. This collapses the
/// fallback's two former entries into one, so the per-binding
/// one-shot guard is encoded directly in the shared entry's
/// `Cell::take()` -- no separate claim flag needed.
pub
/// A resolved shared capability entry for a specific node.
///
/// Serves two roles. As a native shared entry, [`Capabilities::require_shared`]
/// takes its `produce` cell to mint a `Box<dyn C::Shared>`. As the
/// SharedAsLocal fallback for a binding with no native local entry,
/// [`Capabilities::require_local`] takes the same cell and routes the
/// output through `adapt_as_local` to mint a `Box<dyn C::Local>`.
/// Either path consumes the single underlying [`Cell::take()`], so the
/// per-binding one-shot contract is enforced naturally without an
/// auxiliary claim flag.
pub