Skip to main content

ygopro_handler/
handler.rs

1//! The handler abstraction: extract parameters, produce a response, and combine them.
2//!
3//! This module defines how a handler receives a [`Bundle`] (via [`FromRequest`]), produces
4//! a response (via [`IntoResponse`]), and how responses are combined across the handler
5//! chain ([`Call`]). It also provides the three handler wrappers:
6//! [`tower_handler::TowerHandler`], [`async_handler::AsyncHandler`], and
7//! [`sync_handler::SyncHandler`].
8
9use std::future::Future;
10use std::pin::Pin;
11
12/// The type-erased state carried through the handler chain.
13#[derive(Debug)]
14pub struct State {
15    /// The type-erased state map.
16    pub data: anymap3::Map<dyn std::any::Any + Send + Sync>,
17}
18
19impl State {
20    /// Create an empty state.
21    pub fn new() -> Self {
22        State { data: Default::default() }
23    }
24}
25
26impl Default for State {
27    fn default() -> Self {
28        Self::new()
29    }
30}
31
32/// A value that can be converted into a response.
33pub trait IntoResponse<Res> {
34    /// Convert this value into a response.
35    fn into_response(self) -> Res;
36}
37
38impl<T: Send> IntoResponse<T> for T {
39    fn into_response(self) -> T {
40        self
41    }
42}
43
44/// Define how A value be extracted from a [`Bundle`].
45pub trait FromRequest<Req, State, Res>: Sized
46where
47    Req: Send,
48    State: Send,
49    Res: Send,
50{
51    /// Extract this value from the bundle.
52    fn from_request(bundle: &mut Bundle<Req, State, Res>) -> Option<Self>;
53}
54
55/// A flag that stops the handler chain.
56#[derive(Debug)]
57pub struct StopFlag(pub bool);
58
59impl Default for StopFlag {
60    fn default() -> Self {
61        Self(false)
62    }
63}
64
65/// The container passed through the handler chain, carrying the request, response, state,
66/// and a stop flag.
67#[derive(Debug)]
68#[repr(C)]
69pub struct Bundle<Req, State = crate::handler::State, Res = ()> {
70    /// The request being processed.
71    pub request: Req,
72    /// The response being built.
73    pub response: Res,
74    /// A flag to stop the chain.
75    pub stop_flag: StopFlag,
76    // In order to make multiple Call impl in SyncHandler, we must put state
77    // in the last position because we use the mem-order trick here.
78    /// The state shared across handlers.
79    pub state: State,
80}
81
82impl<Req, State, Res> Bundle<Req, State, Res> {
83    /// Create a bundle from a request, state, and response.
84    pub fn new(request: Req, state: State, response: Res) -> Self {
85        Bundle { request, state, response, stop_flag: Default::default() }
86    }
87}
88
89/// A handler that takes extracted parameters and returns a future yielding a response.
90pub trait Handler<T, Req, State, Res>: Clone + Send + Sync + Sized + 'static
91where
92    State: Send,
93{
94    /// The future produced when calling the handler.
95    type Future: Future<Output = Option<Res>> + Send;
96
97    /// Call the handler with the bundle.
98    fn call(&self, bundle: &mut Bundle<Req, State, Res>) -> Self::Future;
99}
100
101impl<F, Fut, Output, Req, State, Res> Handler<((),), Req, State, Res> for F
102where
103    F: Fn() -> Fut + Clone + Send + Sync + 'static,
104    Fut: Future<Output = Output> + Send + 'static,
105    Output: IntoResponse<Res> + 'static,
106    Req: Send + 'static,
107    State: Send + 'static,
108    Res: Send + 'static,
109{
110    type Future = Pin<Box<dyn Future<Output = Option<Res>> + Send>>;
111
112    fn call(&self, _bundle: &mut Bundle<Req, State, Res>) -> Self::Future {
113        let fut = (self)();
114        Box::pin(async move { Some(fut.await.into_response()) })
115    }
116}
117
118impl<F, Output, Req, State, Res> Handler<Option<()>, Req, State, Res> for F
119where
120    F: Fn() -> Output + Clone + Send + Sync + 'static,
121    Output: IntoResponse<Res> + 'static,
122    Req: Send,
123    State: Send,
124    Res: Send,
125{
126    type Future = std::future::Ready<Option<Res>>;
127
128    fn call(&self, _bundle: &mut Bundle<Req, State, Res>) -> Self::Future {
129        std::future::ready(Some((self)().into_response()))
130    }
131}
132
133macro_rules! impl_handler {
134    ([$($ty:ident),*], $last:ident) => {
135        #[allow(non_snake_case, unused_mut)]
136        impl<F, Fut, Output, Req, State, Res, $($ty,)* $last> Handler<((), $($ty,)* $last,), Req, State, Res> for F
137        where
138            F: Fn($($ty,)* $last,) -> Fut + Clone + Send + Sync + 'static,
139            Fut: Future<Output = Output> + Send + 'static,
140            Output: IntoResponse<Res> + 'static,
141            Req: Send + 'static,
142            State: Send + 'static,
143            Res: Send + 'static,
144            $( $ty: FromRequest<Req, State, Res> + Send + 'static, )*
145            $last: FromRequest<Req, State, Res> + Send + 'static,
146        {
147            type Future = Pin<Box<dyn Future<Output = Option<Res>> + Send>>;
148
149            fn call(&self, bundle: &mut Bundle<Req, State, Res>) -> Self::Future {
150                $(
151                    let $ty = match $ty::from_request(bundle) {
152                        Some(value) => value,
153                        None => return Box::pin(std::future::ready(None)),
154                    };
155                )*
156
157                let $last = match $last::from_request(bundle) {
158                    Some(value) => value,
159                    None => return Box::pin(std::future::ready(None)),
160                };
161
162                let handler = self.clone();
163                Box::pin(async move {
164                    let fut = handler($($ty,)* $last,);
165                    Some(fut.await.into_response())
166                })
167            }
168        }
169
170        #[allow(non_snake_case, unused_mut)]
171        impl<F, Output, Req, State, Res, $($ty,)* $last> Handler<Option<((), $($ty,)* $last,)>, Req, State, Res> for F
172        where
173            F: Fn($($ty,)* $last,) -> Output + Clone + Send + Sync + 'static,
174            Output: IntoResponse<Res> + 'static,
175            Req: Send,
176            State: Send,
177            Res: Send,
178            $( $ty: FromRequest<Req, State, Res> + Send, )*
179            $last: FromRequest<Req, State, Res> + Send,
180        {
181            type Future = std::future::Ready<Option<Res>>;
182
183            fn call(&self, bundle: &mut Bundle<Req, State, Res>) -> Self::Future {
184                $(
185                    let $ty = match $ty::from_request(bundle) {
186                        Some(value) => value,
187                        None => return std::future::ready(None),
188                    };
189                )*
190
191                let $last = match $last::from_request(bundle) {
192                    Some(value) => value,
193                    None => return std::future::ready(None),
194                };
195
196                std::future::ready(Some((self)($($ty,)* $last,).into_response()))
197            }
198        }
199    };
200}
201
202impl_handler!([], T1);
203impl_handler!([T1], T2);
204impl_handler!([T1, T2], T3);
205impl_handler!([T1, T2, T3], T4);
206impl_handler!([T1, T2, T3, T4], T5);
207impl_handler!([T1, T2, T3, T4, T5], T6);
208impl_handler!([T1, T2, T3, T4, T5, T6], T7);
209impl_handler!([T1, T2, T3, T4, T5, T6, T7], T8);
210impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8], T9);
211impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9], T10);
212impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10], T11);
213impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], T12);
214impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], T13);
215impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], T14);
216impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], T15);
217impl_handler!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], T16);
218
219/// A type-erased handler callable with a whole bundle.
220pub trait Call<Req, State, Res>: Send + Sync {
221    /// Call the handler, returning the updated bundle.
222    fn call(&self, bundle: Bundle<Req, State, Res>) -> Pin<Box<dyn Future<Output = Bundle<Req, State, Res>> + Send>>;
223    /// The handler's priority, used to sort the chain.
224    fn priority(&self) -> u8;
225}
226
227/// A handler wrapper that integrates with the tower ecosystem.
228pub mod tower_handler {
229    use std::convert::Infallible;
230    use std::future::Future;
231    use std::marker::PhantomData;
232    use std::pin::Pin;
233    use std::task::Poll;
234
235    use tower::Service;
236    use tower::ServiceExt;
237    use tower::util::BoxCloneService;
238
239    use super::Bundle;
240    use super::Call;
241    use super::Handler;
242
243    struct HandlerService<H, T, Req, State, Res> {
244        handler: H,
245        _marker: PhantomData<fn() -> (T, Req, State, Res)>,
246    }
247
248    impl<H, T, Req, State, Res> HandlerService<H, T, Req, State, Res> {
249        fn new(handler: H) -> Self {
250            Self { handler, _marker: PhantomData }
251        }
252    }
253
254    impl<H, T, Req, State, Res> Clone for HandlerService<H, T, Req, State, Res>
255    where
256        H: Clone,
257    {
258        fn clone(&self) -> Self {
259            Self { handler: self.handler.clone(), _marker: PhantomData }
260        }
261    }
262
263    impl<H, T, Req, State, Res> Service<Bundle<Req, State, Res>> for HandlerService<H, T, Req, State, Res>
264    where
265        H: Handler<T, Req, State, Res> + Clone,
266        Req: Send + 'static,
267        State: Send + 'static,
268        Res: Send + 'static + std::ops::Mul<Output = Res>,
269    {
270        type Response = Bundle<Req, State, Res>;
271        type Error = Infallible;
272        type Future = HandlerServiceFuture<H::Future, Req, State, Res>;
273
274        fn call(&mut self, bundle: Bundle<Req, State, Res>) -> Self::Future {
275            let mut bundle = Box::new(bundle);
276            let future = self.handler.call(&mut *bundle);
277            HandlerServiceFuture { future, bundle: Some(bundle) }
278        }
279
280        fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
281            Poll::Ready(Ok(()))
282        }
283    }
284
285    pin_project_lite::pin_project! {
286                struct HandlerServiceFuture<F, Req, State, Res> {
287            #[pin]
288            future: F,
289            bundle: Option<Box<Bundle<Req, State, Res>>>,
290        }
291    }
292
293    impl<F, Req, State, Res> Future for HandlerServiceFuture<F, Req, State, Res>
294    where
295        F: Future<Output = Option<Res>>,
296        Res: std::ops::Mul<Output = Res>,
297    {
298        type Output = Result<Bundle<Req, State, Res>, Infallible>;
299
300        fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
301            let this = self.project();
302            match this.future.poll(cx) {
303                Poll::Ready(Some(response)) => {
304                    let mut bundle = *this.bundle.take().unwrap();
305                    bundle.response = bundle.response * response;
306                    Poll::Ready(Ok(bundle))
307                }
308                Poll::Ready(None) => {
309                    Poll::Ready(Ok(*this.bundle.take().unwrap()))
310                }
311                Poll::Pending => Poll::Pending,
312            }
313        }
314    }
315
316    /// A type-erased handler backed by a tower [`Service`].
317    ///
318    /// The most feature-complete and the slowest wrapper: it inserts a tower `Service`
319    /// layer (`HandlerService`), a boxed future (`HandlerServiceFuture`), and a
320    /// `BoxCloneService`, so every call pays for several layers of boxing and a
321    /// `oneshot` dispatch.
322    pub struct TowerHandler<Req, State, Res> {
323        /// The boxed tower service.
324        pub service: BoxCloneService<Bundle<Req, State, Res>, Bundle<Req, State, Res>, Infallible>,
325        /// The handler's priority.
326        pub priority: u8,
327        /// The handler's name.
328        pub name: &'static str,
329        /// The module the handler was registered from.
330        pub module_name: &'static str,
331    }
332
333    unsafe impl<Req, State, Res> Sync for TowerHandler<Req, State, Res> {}
334
335    impl<Req, State, Res> TowerHandler<Req, State, Res>
336    where
337        Req: Send + 'static,
338        State: Send + 'static,
339        Res: Send + std::ops::Mul<Output = Res> + 'static,
340    {
341        /// Create a tower-backed handler.
342        pub fn new<T: 'static>(
343            priority: u8,
344            name: &'static str,
345            module_name: &'static str,
346            handler: impl Handler<T, Req, State, Res>,
347        ) -> Self {
348            let service = HandlerService::new(handler);
349            Self {
350                priority,
351                name,
352                module_name,
353                service: BoxCloneService::new(service),
354            }
355        }
356    }
357
358    impl<Req, State, Res> Service<Bundle<Req, State, Res>> for TowerHandler<Req, State, Res>
359    where
360        Req: Send + 'static,
361        State: Send + 'static,
362        Res: Send + 'static,
363    {
364        type Response = Bundle<Req, State, Res>;
365        type Error = Infallible;
366        type Future = futures::future::BoxFuture<'static, Result<Bundle<Req, State, Res>, Infallible>>;
367
368        fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
369            self.service.poll_ready(cx)
370        }
371
372        fn call(&mut self, bundle: Bundle<Req, State, Res>) -> Self::Future {
373            self.service.call(bundle)
374        }
375    }
376
377    impl<Req, State, Res> Clone for TowerHandler<Req, State, Res> {
378        fn clone(&self) -> Self {
379            Self {
380                service: self.service.clone(),
381                priority: self.priority,
382                name: self.name,
383                module_name: self.module_name,
384            }
385        }
386    }
387
388    impl<Req, State, Res> Call<Req, State, Res> for TowerHandler<Req, State, Res>
389    where
390        Req: Send + 'static,
391        State: Send + 'static,
392        Res: Send + 'static,
393    {
394        fn call(&self, bundle: Bundle<Req, State, Res>) -> Pin<Box<dyn Future<Output = Bundle<Req, State, Res>> + Send>> {
395            let service = self.service.clone();
396            Box::pin(async move { service.oneshot(bundle).await.unwrap() })
397        }
398
399        fn priority(&self) -> u8 {
400            self.priority
401        }
402    }
403}
404
405/// A type-erased asynchronous handler.
406pub mod async_handler {
407    use std::future::Future;
408    use std::marker::PhantomData;
409    use std::pin::Pin;
410    use std::sync::Arc;
411
412    use super::Bundle;
413    use super::Call;
414    use super::Handler;
415
416    struct HandlerWrapper<H, T, Req, State, Res> {
417        handler: H,
418        priority: u8,
419        _phantom: PhantomData<fn() -> (T, Req, State, Res)>,
420    }
421
422    impl<H, T, Req, State, Res> Clone for HandlerWrapper<H, T, Req, State, Res>
423    where
424        H: Clone,
425    {
426        fn clone(&self) -> Self {
427            Self {
428                handler: self.handler.clone(),
429                priority: self.priority,
430                _phantom: PhantomData,
431            }
432        }
433    }
434
435    impl<H, T, Req, State, Res> Call<Req, State, Res> for HandlerWrapper<H, T, Req, State, Res>
436    where
437        H: Handler<T, Req, State, Res>,
438        <H as Handler<T, Req, State, Res>>::Future: 'static,
439        T: 'static,
440        Req: Send + 'static,
441        State: Send + 'static,
442        Res: Send + std::ops::Mul<Output = Res> + 'static,
443    {
444        fn call(&self, bundle: Bundle<Req, State, Res>) -> Pin<Box<dyn Future<Output = Bundle<Req, State, Res>> + Send>> {
445            let handler = self.handler.clone();
446            Box::pin(async move {
447                let mut bundle = bundle;
448                if let Some(response) = handler.call(&mut bundle).await {
449                    bundle.response = bundle.response * response;
450                }
451                bundle
452            })
453        }
454
455        fn priority(&self) -> u8 {
456            self.priority
457        }
458    }
459
460    /// A type-erased asynchronous handler held in an [`Arc`].
461    ///
462    /// It gives up the tower adaptation layer, holding the handler in an `Arc<dyn Call>`
463    /// and boxing only the future. This drops the extra `Service` boxing while staying
464    /// cloneable through a cheap `Arc` clone.
465    pub struct AsyncHandler<Req, State, Res> {
466        /// The handler's name.
467        pub name: &'static str,
468        /// The module the handler was registered from.
469        pub module_name: &'static str,
470        handler: Arc<dyn Call<Req, State, Res>>,
471    }
472
473    impl<Req, State, Res> Clone for AsyncHandler<Req, State, Res> {
474        fn clone(&self) -> Self {
475            Self {
476                name: self.name,
477                module_name: self.module_name,
478                handler: self.handler.clone(),
479            }
480        }
481    }
482
483    impl<Req, State, Res> AsyncHandler<Req, State, Res>
484    where
485        Req: Send + 'static,
486        State: Send + 'static,
487        Res: Send + std::ops::Mul<Output = Res> + 'static,
488    {
489        /// Create an async handler.
490        pub fn new<T: 'static, H: Handler<T, Req, State, Res>>(
491            priority: u8,
492            name: &'static str,
493            module_name: &'static str,
494            handler: H,
495        ) -> Self
496        where
497            <H as Handler<T, Req, State, Res>>::Future: 'static,
498        {
499            let wrapper = HandlerWrapper {
500                handler,
501                priority,
502                _phantom: PhantomData,
503            };
504            Self {
505                name,
506                module_name,
507                handler: Arc::new(wrapper),
508            }
509        }
510    }
511
512    impl<Req, State, Res> Call<Req, State, Res> for AsyncHandler<Req, State, Res>
513    where
514        Req: Send + 'static,
515        State: Send + 'static,
516        Res: Send + 'static,
517    {
518        fn call(&self, bundle: Bundle<Req, State, Res>) -> Pin<Box<dyn Future<Output = Bundle<Req, State, Res>> + Send>> {
519            self.handler.call(bundle)
520        }
521
522        fn priority(&self) -> u8 {
523            self.handler.priority()
524        }
525    }
526}
527
528/// A type-erased synchronous handler.
529pub mod sync_handler {
530    use std::future::Future;
531    use std::pin::Pin;
532
533    use super::Bundle;
534    use super::Call;
535    use super::Handler;
536
537    /// Type-erased synchronous handler wrapper.
538    ///
539    /// Uses raw pointers and monomorphized function pointers to achieve type erasure
540    /// without requiring `'static` bounds on `Req`, `State`, `Res`, or the handler's
541    /// type parameter `T`. It gives up the async nature of [`Handler`] (its future is
542    /// always `Ready`), in exchange boxing nothing per call and enabling the dual-state
543    /// trick ([`WithSubState`]).
544    ///
545    /// The caller is responsible for ensuring soundness.
546    #[repr(C)]
547    pub struct SyncHandler<Req, State, Res> {
548        /// The handler's name. It is often function name.
549        pub name: &'static str,
550        /// The module the handler was registered from. It is often produced by `module_path!()`.
551        pub module_name: &'static str,
552        priority: u8,
553        handler_pointer: *const (),
554        call_fn: unsafe fn(*const (), &mut Bundle<Req, State, Res>) -> Option<Res>,
555        clone_fn: unsafe fn(*const ()) -> *const (),
556        drop_fn: unsafe fn(*const ()),
557    }
558
559    /// Safety: the stored handler satisfies `Send + Sync` via the `Handler` trait bound.
560    unsafe impl<Req, State, Res> Send for SyncHandler<Req, State, Res> {}
561    /// Safety: the stored handler satisfies `Send + Sync` via the `Handler` trait bound.
562    unsafe impl<Req, State, Res> Sync for SyncHandler<Req, State, Res> {}
563
564    impl<Req, State, Res> SyncHandler<Req, State, Res>
565    where
566        Req: Send,
567        State: Send,
568        Res: Send,
569    {
570        /// Create a synchronous handler.
571        pub fn new<T, H: Handler<T, Req, State, Res, Future = std::future::Ready<Option<Res>>>>(
572            priority: u8,
573            name: &'static str,
574            module_name: &'static str,
575            handler: H,
576        ) -> Self {
577            let handler_pointer = Box::into_raw(Box::new(handler)) as *const ();
578
579            unsafe fn call_erased<H, T, Req, State, Res>(
580                pointer: *const (),
581                bundle: &mut Bundle<Req, State, Res>,
582            ) -> Option<Res>
583            where
584                H: Handler<T, Req, State, Res, Future = std::future::Ready<Option<Res>>>,
585                State: Send,
586            {
587                let handler = unsafe { &*(pointer as *const H) };
588                handler.call(bundle).into_inner()
589            }
590
591            unsafe fn clone_erased<H: Clone>(pointer: *const ()) -> *const () {
592                let handler = unsafe { &*(pointer as *const H) };
593                Box::into_raw(Box::new(handler.clone())) as *const ()
594            }
595
596            unsafe fn drop_erased<H>(pointer: *const ()) {
597                drop(unsafe { Box::from_raw(pointer as *mut H) });
598            }
599
600            Self {
601                name,
602                module_name,
603                priority,
604                handler_pointer,
605                call_fn: call_erased::<H, T, Req, State, Res>,
606                clone_fn: clone_erased::<H>,
607                drop_fn: drop_erased::<H>,
608            }
609        }
610    }
611
612    impl<Req, State, Res> Clone for SyncHandler<Req, State, Res> {
613        fn clone(&self) -> Self {
614            Self {
615                name: self.name,
616                module_name: self.module_name,
617                priority: self.priority,
618                handler_pointer: unsafe { (self.clone_fn)(self.handler_pointer) },
619                call_fn: self.call_fn,
620                clone_fn: self.clone_fn,
621                drop_fn: self.drop_fn,
622            }
623        }
624    }
625
626    impl<Req, State, Res> Drop for SyncHandler<Req, State, Res> {
627        fn drop(&mut self) {
628            unsafe { (self.drop_fn)(self.handler_pointer) }
629        }
630    }
631
632    impl<Req, SubState, Target, Res> Call<Req, Target, Res> for SyncHandler<Req, SubState, Res>
633    where
634        Req: Send + 'static,
635        SubState: Send + 'static,
636        Target: Send + 'static + WithSubState<SubState>,
637        Res: Send + std::ops::Mul<Output = Res> + 'static,
638    {
639        fn call(&self, bundle: Bundle<Req, Target, Res>) -> Pin<Box<dyn Future<Output = Bundle<Req, Target, Res>> + Send>> {
640            let mut bundle = bundle;
641            let result = unsafe {
642                // safety: Target: WithSubState<SubState> makes SubState a layout prefix of Target,
643                // and Bundle putting state last keeps the leading fields at identical offsets.
644                let sub_bundle = &mut *(&mut bundle as *mut Bundle<Req, Target, Res> as *mut Bundle<Req, SubState, Res>);
645                (self.call_fn)(self.handler_pointer, sub_bundle)
646            };
647            if let Some(response) = result {
648                bundle.response = bundle.response * response;
649            }
650            Box::pin(async move { bundle })
651        }
652
653        fn priority(&self) -> u8 {
654            self.priority
655        }
656    }
657
658    /// A state whose `states` map is the leading field (offset 0) and whose `duel`
659    /// field follows at the same offset as `SubState`'s, so that `&mut Self` can be
660    /// reinterpreted as `&mut SubState`.
661    ///
662    /// # Safety
663    /// The implementor must guarantee that every field of `SubState` the handler
664    /// will read through the reinterpreted view resides at the same offset in
665    /// `Self`. For duel states this holds because the `states` map comes first in
666    /// both (offset 0) and `Self`'s duel starts with `SubState`'s duel as a prefix.
667    pub unsafe trait WithSubState<SubState> {}
668
669    unsafe impl<T> WithSubState<T> for T {}
670
671    /// Assert the layout of [`SyncHandler`] is identical across two state types.
672    pub fn assert_sync_handler_layout<Req, SubState, Target, Res>() {
673        const {
674            assert!(std::mem::size_of::<SyncHandler<Req, SubState, Res>>() == std::mem::size_of::<SyncHandler<Req, Target, Res>>());
675            assert!(std::mem::align_of::<SyncHandler<Req, SubState, Res>>() == std::mem::align_of::<SyncHandler<Req, Target, Res>>());
676            assert!(std::mem::offset_of!(SyncHandler<Req, SubState, Res>, call_fn) == std::mem::offset_of!(SyncHandler<Req, Target, Res>, call_fn));
677            assert!(std::mem::offset_of!(SyncHandler<Req, SubState, Res>, handler_pointer) == std::mem::offset_of!(SyncHandler<Req, Target, Res>, handler_pointer));
678        };
679    }
680}