1mod epoch;
2pub mod indices;
3use core::{hash, marker, mem, num};
4
5pub use epoch::Epoch;
6use indices::SlotIndex;
7pub use token::Token;
8pub(crate) use token::{Brand, OutboundKey};
9
10use crate::driver::route;
11
12pub mod lease;
13pub(in crate::driver) mod queues;
14pub mod raw;
15pub mod table;
16mod token;
17
18pub(crate) const FRAMEWORK: u8 = 255;
19pub(crate) const CAPACITY: usize = u8::MAX as usize + 1;
20
21pub(crate) const SHIFT: u32 = 56;
22pub(crate) const KIND_SHIFT: u32 = 48;
23pub const SLOT_BITS: u32 = 24;
24pub const SLOT_MASK: u64 = (1 << SLOT_BITS) - 1;
25pub(crate) const AUX_SHIFT: u32 = SLOT_BITS;
26pub(crate) const AUX_BITS: u32 = KIND_SHIFT - AUX_SHIFT;
27pub(crate) const AUX_VALUE_MASK: u32 = (1 << AUX_BITS) - 1;
28pub(crate) const AUX_MASK: u64 = (AUX_VALUE_MASK as u64) << AUX_SHIFT;
29
30#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
33#[repr(transparent)]
34pub struct Id(u8);
35
36#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
38#[repr(transparent)]
39pub struct Route(u8);
40
41impl Id {
42 pub const fn fixed<const ID: u8>() -> Self {
43 const { assert!(ID != FRAMEWORK, "framework route is reserved") };
44 Self(ID)
45 }
46
47 pub const fn raw(self) -> u8 {
49 self.0
50 }
51
52 pub(crate) const fn into_route(self) -> Route {
53 Route(self.0)
54 }
55}
56
57impl Route {
58 pub(crate) const FRAMEWORK: Self = Self(FRAMEWORK);
59
60 pub(crate) const fn app(self) -> Option<Id> {
61 if self.is_framework() {
62 None
63 } else {
64 Some(Id(self.0))
65 }
66 }
67
68 pub(crate) const fn from_bits(raw: u8) -> Self {
69 Self(raw)
70 }
71
72 pub const fn is_framework(self) -> bool {
73 self.0 == FRAMEWORK
74 }
75
76 pub(crate) const fn raw(self) -> u8 {
77 self.0
78 }
79}
80
81impl From<Id> for Route {
82 fn from(id: Id) -> Self {
83 Self(id.raw())
84 }
85}
86
87impl TryFrom<Route> for Id {
88 type Error = Route;
89
90 fn try_from(route: Route) -> Result<Self, Self::Error> {
91 route.app().ok_or(route)
92 }
93}
94
95#[derive(Clone, Copy, Debug)]
99pub struct KeyTag<const ROUTE: u8, C: kind::Class = kind::Any>(marker::PhantomData<C>);
100
101#[derive(Clone, Copy)]
103pub struct FrameworkTag<C: kind::Class>(marker::PhantomData<C>);
104
105pub trait Tag: Copy {
107 const ROUTE: Route;
108 type Class: kind::Class;
109}
110
111pub trait Select<C: kind::Class>: Tag {}
113
114pub trait App: Tag + kind::Sealed {
116 const ID: Id;
117}
118
119pub trait Identity:
124 App<Class = kind::Any>
125 + Eq
126 + hash::Hash
127 + Materialize<kind::Accept>
128 + Materialize<kind::Recv>
129 + Materialize<kind::Send>
130 + Materialize<kind::Socket>
131 + Materialize<kind::Connect>
132 + Materialize<kind::Shutdown>
133 + Materialize<kind::Open>
134 + Materialize<kind::OneShot>
135 + Materialize<kind::TaskQueue>
136 + Materialize<kind::Tuning>
137 + Materialize<kind::Write>
138 + Materialize<kind::Sync>
139{
140}
141
142pub trait Materialize<C: kind::Class>: Tag<Class = kind::Any> {
147 type With: App<Class = C> + Select<C>;
148}
149
150impl<const ROUTE: u8> Identity for KeyTag<ROUTE, kind::Any> {}
151
152impl<const ROUTE: u8, C: kind::Class> Materialize<C> for KeyTag<ROUTE, kind::Any>
153where
154 KeyTag<ROUTE, C>: App<Class = C> + Select<C>,
155{
156 type With = KeyTag<ROUTE, C>;
157}
158
159impl<const ROUTE: u8, C: kind::Class> PartialEq for KeyTag<ROUTE, C> {
162 fn eq(&self, _: &Self) -> bool {
163 true
164 }
165}
166
167impl<const ROUTE: u8, C: kind::Class> Eq for KeyTag<ROUTE, C> {}
168
169impl<const ROUTE: u8, C: kind::Class> hash::Hash for KeyTag<ROUTE, C> {
170 fn hash<H: hash::Hasher>(&self, state: &mut H) {
171 state.write_u8(ROUTE);
172 }
173}
174
175impl<const ROUTE: u8, C: kind::Class> Tag for KeyTag<ROUTE, C> {
176 const ROUTE: Route = Id::fixed::<ROUTE>().into_route();
177 type Class = C;
178}
179
180impl<const ROUTE: u8, C: kind::Class> App for KeyTag<ROUTE, C> {
181 const ID: Id = Id::fixed::<ROUTE>();
182}
183
184impl<const ROUTE: u8, C: kind::Class> kind::Sealed for KeyTag<ROUTE, C> {}
185
186impl<C: kind::Class> Tag for FrameworkTag<C> {
187 const ROUTE: Route = Route::FRAMEWORK;
188 type Class = C;
189}
190
191impl<T: Tag<Class = kind::Any>, C: kind::Class> Select<C> for T {}
192#[derive(Clone, Copy)]
194#[repr(transparent)]
195pub struct Operation<'d, T: Tag, C: kind::Class = <T as Tag>::Class> {
196 token: Token,
197 driver: Brand<'d, T>,
198 class: marker::PhantomData<C>,
199}
200
201impl<'d, T: Tag, C: kind::Class> Operation<'d, T, C> {
202 pub(super) const fn new(token: Token, driver: Brand<'d, T>) -> Self {
203 Self {
204 token,
205 driver,
206 class: marker::PhantomData,
207 }
208 }
209
210 pub fn matches(self, target: Erased<'d, C>) -> bool {
211 self.token == target.token
212 }
213
214 pub const fn parts(self) -> table::Parts<T> {
215 table::Parts::new(self.token.slot(), self.token.epoch())
216 }
217
218 pub const fn erase_route(self) -> Erased<'d, C> {
219 Erased::new(self.token, self.driver.driver).bind(kind::Witness(self.class))
220 }
221
222 pub(crate) const fn into_token(self) -> Token {
223 self.token
224 }
225}
226
227impl<T: Tag, C: kind::Class> PartialEq for Operation<'_, T, C> {
228 fn eq(&self, other: &Self) -> bool {
229 self.token == other.token
230 }
231}
232
233impl<T: Tag, C: kind::Class> Eq for Operation<'_, T, C> {}
234
235impl<T: Tag, C: kind::Class> hash::Hash for Operation<'_, T, C> {
236 fn hash<H: hash::Hasher>(&self, state: &mut H) {
237 self.token.hash(state);
238 }
239}
240
241#[derive(Clone, Copy)]
243#[repr(transparent)]
244pub struct Erased<'d, C: kind::Class> {
245 pub(in crate::driver) token: Token,
246 pub(in crate::driver) driver: super::Invariant<'d>,
247 pub(in crate::driver) class: marker::PhantomData<C>,
248}
249
250impl<'d> Erased<'d, kind::Any> {
251 pub(in crate::driver) const fn new(token: Token, driver: super::Invariant<'d>) -> Self {
252 Self {
253 token,
254 driver,
255 class: marker::PhantomData,
256 }
257 }
258
259 pub(crate) const fn bind<C: kind::Class>(self, proof: kind::Witness<C>) -> Erased<'d, C> {
260 let kind::Witness(class) = proof;
261 Erased {
262 token: self.token,
263 driver: self.driver,
264 class,
265 }
266 }
267}
268
269impl<'d, C: kind::Class> Erased<'d, C> {
270 pub fn matches(self, target: Self) -> bool {
271 self.token == target.token
272 }
273
274 pub const fn route(self) -> Route {
275 self.token.route()
276 }
277
278 pub const fn slot(self) -> SlotIndex {
279 self.token.slot()
280 }
281
282 pub const fn epoch(self) -> Epoch {
283 self.token.epoch()
284 }
285
286 pub(crate) const fn into_token(self) -> Token {
287 self.token
288 }
289}
290
291pub struct Mismatch<'d, T: Tag, C: kind::Class> {
293 target: Erased<'d, C>,
294 tag: marker::PhantomData<T>,
295}
296
297impl<'d, T: Tag, C: kind::Class> Mismatch<'d, T, C> {
298 const fn new(target: Erased<'d, C>) -> Self {
299 Self {
300 target,
301 tag: marker::PhantomData,
302 }
303 }
304
305 pub fn into_target(self) -> Erased<'d, C> {
306 self.target
307 }
308}
309
310pub mod kind;
311
312pub const SHUTDOWN: Control = Control::new(<kind::Shutdown as kind::Class>::CODE, SlotIndex::ZERO);
313
314const _: () = {
315 assert!(mem::size_of::<Erased<'static, kind::Send>>() == mem::size_of::<Token>());
316 assert!(mem::align_of::<Erased<'static, kind::Send>>() == mem::align_of::<Token>());
317 assert!(mem::size_of::<Mismatch<'static, KeyTag<1>, kind::Send>>() == mem::size_of::<Token>());
318};
319const _: () = assert!(mem::size_of::<Id>() == mem::size_of::<u8>());
320const _: () = assert!(mem::size_of::<Route>() == mem::size_of::<u8>());
321const _: () = {
322 assert!(mem::size_of::<Operation<'static, KeyTag<1>>>() == mem::size_of::<Token>());
323 assert!(mem::align_of::<Operation<'static, KeyTag<1>>>() == mem::align_of::<Token>());
324};
325
326#[derive(Clone, Copy, Eq, PartialEq, Debug)]
328#[repr(transparent)]
329pub struct Control(num::NonZero<u64>);
330
331impl From<Control> for num::NonZero<u64> {
332 fn from(control: Control) -> Self {
333 control.0
334 }
335}
336
337impl Control {
338 pub(crate) const fn new(kind: kind::Code, slot: indices::SlotIndex) -> Self {
339 let raw = ((route::FRAMEWORK as u64) << route::SHIFT)
340 | ((kind.raw() as u64) << route::KIND_SHIFT)
341 | slot.raw() as u64;
342 Self(unsafe { num::NonZero::<u64>::new_unchecked(raw) })
344 }
345
346 pub const fn slot(self) -> indices::SlotIndex {
347 indices::SlotIndex::from_field(self.0.get())
348 }
349}
350
351impl TryFrom<u64> for Control {
352 type Error = u64;
353
354 fn try_from(raw: u64) -> Result<Self, Self::Error> {
355 if (raw >> route::SHIFT) as u8 != route::FRAMEWORK {
356 return Err(raw);
357 }
358 Ok(Self(unsafe { num::NonZero::<u64>::new_unchecked(raw) }))
360 }
361}
362
363const _: () = {
364 assert!(mem::size_of::<Token>() == 2 * mem::size_of::<u64>());
365 assert!(mem::size_of::<Option<Token>>() == mem::size_of::<Token>());
366 assert!(mem::size_of::<Control>() == mem::size_of::<u64>());
367 assert!(mem::size_of::<Option<Control>>() == mem::size_of::<Control>());
368};
369
370#[derive(Clone, Copy)]
372pub struct Space<'d, Tag: route::Tag> {
373 pub(in crate::driver) driver: route::Brand<'d, Tag>,
374}
375
376impl<'d, Tag: route::Tag> Space<'d, Tag> {
377 pub const fn bind(
378 self,
379 slot: indices::SlotIndex,
380 epoch: route::Epoch,
381 ) -> route::Target<'d, Tag> {
382 route::Target::from_parts(table::Parts::new(slot, epoch), self.driver)
383 }
384
385 pub fn parse<C: kind::Class>(
386 self,
387 target: route::Erased<'d, C>,
388 ) -> Result<route::Operation<'d, Tag, C>, route::Mismatch<'d, Tag, C>>
389 where
390 Tag: route::Select<C>,
391 {
392 if target.route() != Tag::ROUTE {
393 return Err(route::Mismatch::new(target));
394 }
395 Ok(route::Operation::new(target.into_token(), self.driver))
396 }
397}
398
399const _: () = assert!(mem::size_of::<Space<'static, route::KeyTag<1>>>() == 0);
400
401#[derive(Clone, Copy, Debug)]
404#[repr(transparent)]
405pub struct Target<'d, Tag: route::Tag> {
406 parts: table::Parts<Tag>,
407 pub(in crate::driver) driver: route::Brand<'d, Tag>,
408}
409
410impl<'d, Tag: route::Tag> Target<'d, Tag> {
411 pub(in crate::driver::route) const fn from_parts(
412 parts: table::Parts<Tag>,
413 driver: route::Brand<'d, Tag>,
414 ) -> Self {
415 Self { parts, driver }
416 }
417
418 pub const fn parts(self) -> table::Parts<Tag> {
419 self.parts
420 }
421
422 pub const fn slot(self) -> indices::SlotIndex {
423 self.parts.slot()
424 }
425
426 pub const fn epoch(self) -> route::Epoch {
427 self.parts.epoch()
428 }
429
430 pub const fn bind<T>(self, value: T) -> route::Bound<'d, Tag, T> {
431 route::Bound::new(self, value)
432 }
433
434 pub const fn operation<C: kind::Class>(self) -> route::Operation<'d, Tag, C>
435 where
436 Tag: route::Select<C>,
437 {
438 let Self { parts, driver } = self;
439 route::Operation::new(route::Token::encode::<Tag, C>(parts), driver)
440 }
441
442 pub const fn dispatch(self) -> route::Operation<'d, Tag> {
443 let Self { parts, driver } = self;
444 route::Operation::new(route::Token::from_parts(parts), driver)
445 }
446}
447
448impl<'d, Tag: route::Tag, C: kind::Class> From<&route::Operation<'d, Tag, C>> for Target<'d, Tag> {
449 fn from(op: &route::Operation<'d, Tag, C>) -> Self {
450 Self {
451 parts: op.parts(),
452 driver: op.driver,
453 }
454 }
455}
456
457impl<Tag: route::Tag> PartialEq for Target<'_, Tag> {
458 fn eq(&self, other: &Self) -> bool {
459 self.parts == other.parts
460 }
461}
462
463impl<Tag: route::Tag> Eq for Target<'_, Tag> {}
464
465impl<Tag: route::Tag> hash::Hash for Target<'_, Tag> {
466 fn hash<H: hash::Hasher>(&self, state: &mut H) {
467 self.parts.hash(state);
468 }
469}
470
471const _: () = {
472 assert!(mem::size_of::<Target<'static, route::KeyTag<1>>>() == mem::size_of::<route::Token>());
473 assert!(
474 mem::align_of::<Target<'static, route::KeyTag<1>>>() == mem::align_of::<route::Token>()
475 );
476};
477
478#[must_use = "bound submission input must be submitted or dropped"]
481pub struct Bound<'d, Tag: route::Tag, T> {
482 target: route::Target<'d, Tag>,
483 value: T,
484}
485
486impl<'d, Tag: route::Tag, T> Bound<'d, Tag, T> {
487 pub(in crate::driver::route) const fn new(target: route::Target<'d, Tag>, value: T) -> Self {
488 Self { target, value }
489 }
490
491 pub(crate) fn into_parts(self) -> (route::Target<'d, Tag>, T) {
492 (self.target, self.value)
493 }
494}