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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
//! Service registry for cross-module service discovery.
//!
//! Provides two registry types:
//! - [`ServiceRegistry`]: For unique services (one provider per type)
//! - [`MultiServiceRegistry`]: For keyed services (multiple providers with typed keys)
//!
//! # Architecture
//!
//! This module implements the **generic mechanism** for service discovery.
//! Specific service traits and typed keys are defined in their respective drivers.
//!
//! ```text
//! server/lib/kernel/api/service/ → Generic ServiceRegistry (this module)
//! server/lib/drivers/vfs/ → VfsScheme enum + VfsProviderRegistry
//! server/lib/drivers/input/ → ModeProviderKey enum + ModeProviderRegistry
//! ```
//!
//! # Example
//!
//! ```ignore
//! use reovim_kernel::api::v1::{ServiceRegistry, MultiServiceRegistry, ServiceKey};
//!
//! // Unique service (one provider per type)
//! let registry = ServiceRegistry::new();
//! registry.register::<MyService>(Arc::new(my_service));
//! let service = registry.get::<MyService>();
//!
//! // Keyed service (multiple providers)
//! let vfs_registry = MultiServiceRegistry::<VfsScheme, dyn VfsDriver>::new();
//! vfs_registry.register(VfsScheme::File, Arc::new(local_fs));
//! let driver = vfs_registry.get(&VfsScheme::File);
//! ```
use ;
use RwLock;
// ============================================================================
// Service Trait
// ============================================================================
/// Marker trait for services that can be registered in [`ServiceRegistry`].
///
/// Implement this trait for types that should be discoverable via the
/// service registry. The trait bounds ensure thread-safety.
// ============================================================================
// ServiceKey Trait (typed key marker)
// ============================================================================
/// Marker trait for typed service keys.
///
/// Each driver defines its own key enum implementing this trait.
/// This ensures compile-time safety and provides metadata for error messages.
///
/// # Safety Contract
///
/// **DO NOT** use `service_name()` for:
/// - Runtime service routing or comparison
/// - Dynamic dispatch based on string matching
/// - Escape hatch to bypass typed key lookup
///
/// The `service_name()` method exists **ONLY** for human-readable error messages.
/// All service lookup MUST use the typed key directly via `get(key)`.
///
/// # Correct Usage
///
/// ```ignore
/// // GOOD: Direct typed key lookup
/// let vfs = registry.get(&VfsScheme::File);
/// ```
///
/// # Incorrect Usage
///
/// ```ignore
/// // BAD: Never compare service_name() for routing
/// if K::service_name() == "VFS" { ... } // WRONG!
///
/// // BAD: Never use as escape hatch
/// fn get_any_service(name: &str) { ... } // WRONG!
/// ```
///
/// # Example
///
/// ```ignore
/// use reovim_kernel::api::v1::ServiceKey;
///
/// #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
/// pub enum VfsScheme {
/// File,
/// Memory,
/// Ssh,
/// }
///
/// impl ServiceKey for VfsScheme {
/// fn service_name() -> &'static str { "VFS" }
/// }
/// ```
// ============================================================================
// Unique Service Registry (one provider per type)
// ============================================================================
/// Registry for unique services - one provider wins per service type.
///
/// Uses `TypeId` internally for type-safe lookup. Each service type can have
/// at most one registered provider; registering a new provider replaces the
/// existing one.
///
/// # Thread Safety
///
/// All operations are protected by `RwLock`, allowing concurrent reads with
/// exclusive writes.
///
/// # Example
///
/// ```ignore
/// use reovim_kernel::api::v1::{Service, ServiceRegistry};
/// use std::sync::Arc;
///
/// struct MyCompositor;
/// impl Service for MyCompositor {}
///
/// let registry = ServiceRegistry::new();
/// registry.register(Arc::new(MyCompositor));
///
/// let compositor = registry.get::<MyCompositor>();
/// assert!(compositor.is_some());
/// ```
// ============================================================================
// Multi Service Registry (multiple providers with typed key lookup)
// ============================================================================
/// Registry for keyed services - multiple providers with typed key-based lookup.
///
/// Generic mechanism in kernel, typed keys defined in drivers.
///
/// # Type Safety
///
/// Uses `K: ServiceKey` bound to ensure only proper service keys can be used.
/// The [`ServiceKey`] trait provides:
/// - Compile-time enforcement (arbitrary types rejected)
/// - Built-in service name for error messages
/// - Self-documenting API
///
/// # Example
///
/// ```ignore
/// use reovim_kernel::api::v1::{MultiServiceRegistry, ServiceKey};
///
/// // In driver: define typed key implementing ServiceKey
/// #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
/// pub enum VfsScheme { File, Memory, Ssh }
///
/// impl ServiceKey for VfsScheme {
/// fn service_name() -> &'static str { "VFS" }
/// }
///
/// // In driver: define type alias with typed key
/// pub type VfsProviderRegistry = MultiServiceRegistry<VfsScheme, dyn VfsDriver>;
///
/// // Usage
/// let registry = VfsProviderRegistry::new();
/// registry.register(VfsScheme::File, Arc::new(local_fs_provider));
/// let provider = registry.get(&VfsScheme::File);
/// ```
// Implement Service so MultiServiceRegistry can be stored in ServiceRegistry
// ============================================================================
// Tests
// ============================================================================