shipyard/borrow/
mod.rs

1mod borrow_info;
2#[cfg(feature = "thread_local")]
3mod non_send;
4#[cfg(feature = "thread_local")]
5mod non_send_sync;
6#[cfg(feature = "thread_local")]
7mod non_sync;
8mod world_borrow;
9
10pub use borrow_info::BorrowInfo;
11#[cfg(feature = "thread_local")]
12pub use non_send::NonSend;
13#[cfg(feature = "thread_local")]
14pub use non_send_sync::NonSendSync;
15#[cfg(feature = "thread_local")]
16pub use non_sync::NonSync;
17pub use world_borrow::WorldBorrow;
18
19use crate::all_storages::{AllStorages, CustomStorageAccess};
20use crate::atomic_refcell::{ARef, ARefMut, SharedBorrow};
21use crate::component::{Component, Unique};
22use crate::error;
23use crate::sparse_set::SparseSet;
24#[cfg(feature = "thread_local")]
25use crate::storage::StorageId;
26use crate::system::Nothing;
27use crate::tracking::{Tracking, TrackingTimestamp};
28use crate::unique::UniqueStorage;
29use crate::views::{EntitiesView, EntitiesViewMut, UniqueView, UniqueViewMut, View, ViewMut};
30use core::marker::PhantomData;
31
32/// Describes if a storage is borrowed exclusively or not.  
33/// It is used to display workloads' borrowing information.
34#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
35#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
36pub enum Mutability {
37    #[allow(missing_docs)]
38    Shared,
39    #[allow(missing_docs)]
40    Exclusive,
41}
42
43/// Allows a type to be borrowed by [`AllStorages::borrow`], [`AllStorages::run`],
44/// [`World::borrow`], [`World::run`] and workloads.
45///
46/// ### Example of manual implementation:
47/// ```rust
48/// use shipyard::{track, advanced::{atomic_refcell::SharedBorrow, tracking::TrackingTimestamp}, all_storages::AllStorages, borrow::Borrow, View, UniqueView};
49///
50/// # struct Camera {}
51/// # impl shipyard::Unique for Camera {}
52/// # struct Position {}
53/// # impl shipyard::Component for Position {
54/// #     type Tracking = track::Untracked;
55/// # }
56/// #
57/// struct CameraView<'v> {
58///     camera: UniqueView<'v, Camera>,
59///     position: View<'v, Position>,
60/// }
61///
62/// impl Borrow for CameraView<'_> {
63///     type View<'v> = CameraView<'v>;
64///
65///     fn borrow<'a>(
66///         all_storages: &'a AllStorages,
67///         all_borrow: Option<SharedBorrow<'a>>,
68///         last_run: Option<TrackingTimestamp>,
69///         current: TrackingTimestamp,
70///     ) -> Result<Self::View<'a>, shipyard::error::GetStorage> {
71///         Ok(CameraView {
72///             camera: UniqueView::<Camera>::borrow(all_storages, all_borrow.clone(), last_run, current)?,
73///             position: View::<Position>::borrow(all_storages, all_borrow, last_run, current)?,
74///         })
75///     }
76/// }
77/// ```
78///
79/// [`World::borrow`]: crate::World::borrow
80/// [`World::run`]: crate::World::run
81pub trait Borrow {
82    #[allow(missing_docs)]
83    type View<'a>;
84
85    /// This function is where the actual borrowing happens.
86    fn borrow<'a>(
87        all_storages: &'a AllStorages,
88        all_borrow: Option<SharedBorrow<'a>>,
89        last_run: Option<TrackingTimestamp>,
90        current: TrackingTimestamp,
91    ) -> Result<Self::View<'a>, error::GetStorage>;
92}
93
94// this is needed for downstream crate to impl System
95impl Borrow for Nothing {
96    type View<'a> = ();
97
98    fn borrow<'a>(
99        _all_storages: &'a AllStorages,
100        _all_borrow: Option<SharedBorrow<'a>>,
101        _last_run: Option<TrackingTimestamp>,
102        _current: TrackingTimestamp,
103    ) -> Result<Self::View<'a>, error::GetStorage> {
104        Ok(())
105    }
106}
107
108impl Borrow for () {
109    type View<'a> = ();
110
111    #[inline]
112    fn borrow<'a>(
113        _all_storages: &'a AllStorages,
114        _all_borrow: Option<SharedBorrow<'a>>,
115        _last_run: Option<TrackingTimestamp>,
116        _current: TrackingTimestamp,
117    ) -> Result<Self::View<'a>, error::GetStorage>
118    where
119        Self: Sized,
120    {
121        Ok(())
122    }
123}
124
125impl Borrow for EntitiesView<'_> {
126    type View<'a> = EntitiesView<'a>;
127
128    #[inline]
129    fn borrow<'a>(
130        all_storages: &'a AllStorages,
131        all_borrow: Option<SharedBorrow<'a>>,
132        _last_run: Option<TrackingTimestamp>,
133        _current: TrackingTimestamp,
134    ) -> Result<Self::View<'a>, error::GetStorage> {
135        let entities = all_storages.entities()?;
136
137        let (entities, borrow) = unsafe { ARef::destructure(entities) };
138
139        Ok(EntitiesView {
140            entities,
141            borrow: Some(borrow),
142            all_borrow,
143        })
144    }
145}
146
147impl Borrow for EntitiesViewMut<'_> {
148    type View<'a> = EntitiesViewMut<'a>;
149
150    #[inline]
151    fn borrow<'a>(
152        all_storages: &'a AllStorages,
153        all_borrow: Option<SharedBorrow<'a>>,
154        _last_run: Option<TrackingTimestamp>,
155        _current: TrackingTimestamp,
156    ) -> Result<Self::View<'a>, error::GetStorage> {
157        let entities = all_storages.entities_mut()?;
158
159        let (entities, borrow) = unsafe { ARefMut::destructure(entities) };
160
161        Ok(EntitiesViewMut {
162            entities,
163            _borrow: Some(borrow),
164            _all_borrow: all_borrow,
165        })
166    }
167}
168
169impl<T: Send + Sync + Component, Track> Borrow for View<'_, T, Track>
170where
171    Track: Tracking,
172{
173    type View<'a> = View<'a, T, Track>;
174
175    #[inline]
176    fn borrow<'a>(
177        all_storages: &'a AllStorages,
178        all_borrow: Option<SharedBorrow<'a>>,
179        last_run: Option<TrackingTimestamp>,
180        current: TrackingTimestamp,
181    ) -> Result<Self::View<'a>, error::GetStorage> {
182        let view = all_storages.custom_storage_or_insert(SparseSet::new)?;
183
184        let (sparse_set, borrow) = unsafe { ARef::destructure(view) };
185
186        sparse_set.check_tracking::<Track>()?;
187
188        Ok(View::new(sparse_set, borrow, all_borrow, last_run, current))
189    }
190}
191
192#[cfg(feature = "thread_local")]
193impl<T: Sync + Component, Track> Borrow for NonSend<View<'_, T, Track>>
194where
195    Track: Tracking,
196{
197    type View<'a> = NonSend<View<'a, T, Track>>;
198
199    #[inline]
200    fn borrow<'a>(
201        all_storages: &'a AllStorages,
202        all_borrow: Option<SharedBorrow<'a>>,
203        last_run: Option<TrackingTimestamp>,
204        current: TrackingTimestamp,
205    ) -> Result<Self::View<'a>, error::GetStorage> {
206        let view = all_storages.custom_storage_or_insert_non_send(|| NonSend(SparseSet::new()))?;
207
208        let (sparse_set, borrow) = unsafe { ARef::destructure(view) };
209
210        sparse_set.check_tracking::<Track>()?;
211
212        Ok(NonSend(View::new(
213            sparse_set, borrow, all_borrow, last_run, current,
214        )))
215    }
216}
217
218#[cfg(feature = "thread_local")]
219impl<T: Send + Component, Track> Borrow for NonSync<View<'_, T, Track>>
220where
221    Track: Tracking,
222{
223    type View<'a> = NonSync<View<'a, T, Track>>;
224
225    #[inline]
226    fn borrow<'a>(
227        all_storages: &'a AllStorages,
228        all_borrow: Option<SharedBorrow<'a>>,
229        last_run: Option<TrackingTimestamp>,
230        current: TrackingTimestamp,
231    ) -> Result<Self::View<'a>, error::GetStorage> {
232        let view = all_storages.custom_storage_or_insert_non_sync(|| NonSync(SparseSet::new()))?;
233
234        let (sparse_set, borrow) = unsafe { ARef::destructure(view) };
235
236        sparse_set.check_tracking::<Track>()?;
237
238        Ok(NonSync(View::new(
239            sparse_set, borrow, all_borrow, last_run, current,
240        )))
241    }
242}
243
244#[cfg(feature = "thread_local")]
245impl<T: Component, Track> Borrow for NonSendSync<View<'_, T, Track>>
246where
247    Track: Tracking,
248{
249    type View<'a> = NonSendSync<View<'a, T, Track>>;
250
251    #[inline]
252    fn borrow<'a>(
253        all_storages: &'a AllStorages,
254        all_borrow: Option<SharedBorrow<'a>>,
255        last_run: Option<TrackingTimestamp>,
256        current: TrackingTimestamp,
257    ) -> Result<Self::View<'a>, error::GetStorage> {
258        let view = all_storages
259            .custom_storage_or_insert_non_send_sync(|| NonSendSync(SparseSet::new()))?;
260
261        let (sparse_set, borrow) = unsafe { ARef::destructure(view) };
262
263        sparse_set.check_tracking::<Track>()?;
264
265        Ok(NonSendSync(View::new(
266            sparse_set, borrow, all_borrow, last_run, current,
267        )))
268    }
269}
270
271impl<T: Send + Sync + Component, Track> Borrow for ViewMut<'_, T, Track>
272where
273    Track: Tracking,
274{
275    type View<'a> = ViewMut<'a, T, Track>;
276
277    #[inline]
278    fn borrow<'a>(
279        all_storages: &'a AllStorages,
280        all_borrow: Option<SharedBorrow<'a>>,
281        last_run: Option<TrackingTimestamp>,
282        current: TrackingTimestamp,
283    ) -> Result<Self::View<'a>, error::GetStorage> {
284        let view = all_storages.custom_storage_or_insert_mut(SparseSet::new)?;
285
286        let (sparse_set, borrow) = unsafe { ARefMut::destructure(view) };
287
288        sparse_set.check_tracking::<Track>()?;
289
290        Ok(ViewMut {
291            last_insertion: last_run.unwrap_or(sparse_set.last_insert),
292            last_modification: last_run.unwrap_or(sparse_set.last_modified),
293            last_removal_or_deletion: last_run.unwrap_or(TrackingTimestamp::origin()),
294            current,
295            sparse_set,
296            borrow,
297            all_borrow,
298            phantom: PhantomData,
299        })
300    }
301}
302
303#[cfg(feature = "thread_local")]
304impl<T: Sync + Component, Track> Borrow for NonSend<ViewMut<'_, T, Track>>
305where
306    Track: Tracking,
307{
308    type View<'a> = NonSend<ViewMut<'a, T, Track>>;
309
310    #[inline]
311    fn borrow<'a>(
312        all_storages: &'a AllStorages,
313        all_borrow: Option<SharedBorrow<'a>>,
314        last_run: Option<TrackingTimestamp>,
315        current: TrackingTimestamp,
316    ) -> Result<Self::View<'a>, error::GetStorage> {
317        let view =
318            all_storages.custom_storage_or_insert_non_send_mut(|| NonSend(SparseSet::new()))?;
319
320        let (sparse_set, borrow) = unsafe { ARefMut::destructure(view) };
321
322        sparse_set.check_tracking::<Track>()?;
323
324        Ok(NonSend(ViewMut {
325            last_insertion: last_run.unwrap_or(sparse_set.last_insert),
326            last_modification: last_run.unwrap_or(sparse_set.last_modified),
327            last_removal_or_deletion: last_run.unwrap_or(TrackingTimestamp::origin()),
328            current,
329            sparse_set,
330            borrow: borrow,
331            all_borrow: all_borrow,
332            phantom: PhantomData,
333        }))
334    }
335}
336
337#[cfg(feature = "thread_local")]
338impl<T: Send + Component, Track> Borrow for NonSync<ViewMut<'_, T, Track>>
339where
340    Track: Tracking,
341{
342    type View<'a> = NonSync<ViewMut<'a, T, Track>>;
343
344    #[inline]
345    fn borrow<'a>(
346        all_storages: &'a AllStorages,
347        all_borrow: Option<SharedBorrow<'a>>,
348        last_run: Option<TrackingTimestamp>,
349        current: TrackingTimestamp,
350    ) -> Result<Self::View<'a>, error::GetStorage> {
351        let view =
352            all_storages.custom_storage_or_insert_non_sync_mut(|| NonSync(SparseSet::new()))?;
353
354        let (sparse_set, borrow) = unsafe { ARefMut::destructure(view) };
355
356        sparse_set.check_tracking::<Track>()?;
357
358        Ok(NonSync(ViewMut {
359            last_insertion: last_run.unwrap_or(sparse_set.last_insert),
360            last_modification: last_run.unwrap_or(sparse_set.last_modified),
361            last_removal_or_deletion: last_run.unwrap_or(TrackingTimestamp::origin()),
362            current,
363            sparse_set,
364            borrow: borrow,
365            all_borrow: all_borrow,
366            phantom: PhantomData,
367        }))
368    }
369}
370
371#[cfg(feature = "thread_local")]
372impl<T: Component, Track> Borrow for NonSendSync<ViewMut<'_, T, Track>>
373where
374    Track: Tracking,
375{
376    type View<'a> = NonSendSync<ViewMut<'a, T, Track>>;
377
378    #[inline]
379    fn borrow<'a>(
380        all_storages: &'a AllStorages,
381        all_borrow: Option<SharedBorrow<'a>>,
382        last_run: Option<TrackingTimestamp>,
383        current: TrackingTimestamp,
384    ) -> Result<Self::View<'a>, error::GetStorage> {
385        let view = all_storages
386            .custom_storage_or_insert_non_send_sync_mut(|| NonSendSync(SparseSet::new()))?;
387
388        let (sparse_set, borrow) = unsafe { ARefMut::destructure(view) };
389
390        sparse_set.check_tracking::<Track>()?;
391
392        Ok(NonSendSync(ViewMut {
393            last_insertion: last_run.unwrap_or(sparse_set.last_insert),
394            last_modification: last_run.unwrap_or(sparse_set.last_modified),
395            last_removal_or_deletion: last_run.unwrap_or(TrackingTimestamp::origin()),
396            current,
397            sparse_set,
398            borrow: borrow,
399            all_borrow: all_borrow,
400            phantom: PhantomData,
401        }))
402    }
403}
404
405impl<T: Send + Sync + Unique> Borrow for UniqueView<'_, T> {
406    type View<'a> = UniqueView<'a, T>;
407
408    #[inline]
409    fn borrow<'a>(
410        all_storages: &'a AllStorages,
411        all_borrow: Option<SharedBorrow<'a>>,
412        last_run: Option<TrackingTimestamp>,
413        current: TrackingTimestamp,
414    ) -> Result<Self::View<'a>, error::GetStorage> {
415        let view = all_storages.custom_storage()?;
416
417        let (unique, borrow) = unsafe { ARef::destructure(view) };
418
419        Ok(UniqueView {
420            unique,
421            borrow: Some(borrow),
422            all_borrow,
423            last_insertion: last_run.unwrap_or(unique.last_insert),
424            last_modification: last_run.unwrap_or(unique.last_modification),
425            current,
426        })
427    }
428}
429
430#[cfg(feature = "thread_local")]
431impl<T: Sync + Unique> Borrow for NonSend<UniqueView<'_, T>> {
432    type View<'a> = NonSend<UniqueView<'a, T>>;
433
434    #[inline]
435    fn borrow<'a>(
436        all_storages: &'a AllStorages,
437        all_borrow: Option<SharedBorrow<'a>>,
438        last_run: Option<TrackingTimestamp>,
439        current: TrackingTimestamp,
440    ) -> Result<Self::View<'a>, error::GetStorage> {
441        let view = all_storages.custom_storage_by_id(StorageId::of::<UniqueStorage<T>>())?;
442        let view = ARef::map(view, |storage| {
443            storage
444                .as_any()
445                .downcast_ref::<NonSend<UniqueStorage<T>>>()
446                .unwrap()
447        });
448
449        let (unique, borrow) = unsafe { ARef::destructure(view) };
450
451        Ok(NonSend(UniqueView {
452            unique,
453            borrow: Some(borrow),
454            all_borrow,
455            last_insertion: last_run.unwrap_or(unique.last_insert),
456            last_modification: last_run.unwrap_or(unique.last_modification),
457            current,
458        }))
459    }
460}
461
462#[cfg(feature = "thread_local")]
463impl<T: Send + Unique> Borrow for NonSync<UniqueView<'_, T>> {
464    type View<'a> = NonSync<UniqueView<'a, T>>;
465
466    #[inline]
467    fn borrow<'a>(
468        all_storages: &'a AllStorages,
469        all_borrow: Option<SharedBorrow<'a>>,
470        last_run: Option<TrackingTimestamp>,
471        current: TrackingTimestamp,
472    ) -> Result<Self::View<'a>, error::GetStorage> {
473        let view = all_storages.custom_storage_by_id(StorageId::of::<UniqueStorage<T>>())?;
474        let view = ARef::map(view, |storage| {
475            storage
476                .as_any()
477                .downcast_ref::<NonSync<UniqueStorage<T>>>()
478                .unwrap()
479        });
480
481        let (unique, borrow) = unsafe { ARef::destructure(view) };
482
483        Ok(NonSync(UniqueView {
484            unique,
485            borrow: Some(borrow),
486            all_borrow,
487            last_insertion: last_run.unwrap_or(unique.last_insert),
488            last_modification: last_run.unwrap_or(unique.last_modification),
489            current,
490        }))
491    }
492}
493
494#[cfg(feature = "thread_local")]
495impl<T: Unique> Borrow for NonSendSync<UniqueView<'_, T>> {
496    type View<'a> = NonSendSync<UniqueView<'a, T>>;
497
498    #[inline]
499    fn borrow<'a>(
500        all_storages: &'a AllStorages,
501        all_borrow: Option<SharedBorrow<'a>>,
502        last_run: Option<TrackingTimestamp>,
503        current: TrackingTimestamp,
504    ) -> Result<Self::View<'a>, error::GetStorage> {
505        let view = all_storages.custom_storage_by_id(StorageId::of::<UniqueStorage<T>>())?;
506        let view = ARef::map(view, |storage| {
507            storage
508                .as_any()
509                .downcast_ref::<NonSendSync<UniqueStorage<T>>>()
510                .unwrap()
511        });
512
513        let (unique, borrow) = unsafe { ARef::destructure(view) };
514
515        Ok(NonSendSync(UniqueView {
516            unique,
517            borrow: Some(borrow),
518            all_borrow,
519            last_insertion: last_run.unwrap_or(unique.last_insert),
520            last_modification: last_run.unwrap_or(unique.last_modification),
521            current,
522        }))
523    }
524}
525
526impl<T: Send + Sync + Unique> Borrow for UniqueViewMut<'_, T> {
527    type View<'a> = UniqueViewMut<'a, T>;
528
529    #[inline]
530    fn borrow<'a>(
531        all_storages: &'a AllStorages,
532        all_borrow: Option<SharedBorrow<'a>>,
533        last_run: Option<TrackingTimestamp>,
534        current: TrackingTimestamp,
535    ) -> Result<Self::View<'a>, error::GetStorage> {
536        let view = all_storages.custom_storage_mut::<UniqueStorage<T>>()?;
537
538        let (unique, borrow) = unsafe { ARefMut::destructure(view) };
539
540        Ok(UniqueViewMut {
541            last_insertion: last_run.unwrap_or(unique.last_insert),
542            last_modification: last_run.unwrap_or(unique.last_modification),
543            current,
544            unique,
545            _borrow: Some(borrow),
546            _all_borrow: all_borrow,
547        })
548    }
549}
550
551#[cfg(feature = "thread_local")]
552impl<T: Sync + Unique> Borrow for NonSend<UniqueViewMut<'_, T>> {
553    type View<'a> = NonSend<UniqueViewMut<'a, T>>;
554
555    #[inline]
556    fn borrow<'a>(
557        all_storages: &'a AllStorages,
558        all_borrow: Option<SharedBorrow<'a>>,
559        last_run: Option<TrackingTimestamp>,
560        current: TrackingTimestamp,
561    ) -> Result<Self::View<'a>, error::GetStorage> {
562        let view = all_storages.custom_storage_mut_by_id(StorageId::of::<UniqueStorage<T>>())?;
563        let view = ARefMut::map(view, |storage| {
564            storage
565                .as_any_mut()
566                .downcast_mut::<NonSend<UniqueStorage<T>>>()
567                .unwrap()
568        });
569
570        let (unique, borrow) = unsafe { ARefMut::destructure(view) };
571
572        Ok(NonSend(UniqueViewMut {
573            last_insertion: last_run.unwrap_or(unique.last_insert),
574            last_modification: last_run.unwrap_or(unique.last_modification),
575            current,
576            unique,
577            _borrow: Some(borrow),
578            _all_borrow: all_borrow,
579        }))
580    }
581}
582
583#[cfg(feature = "thread_local")]
584impl<T: Send + Unique> Borrow for NonSync<UniqueViewMut<'_, T>> {
585    type View<'a> = NonSync<UniqueViewMut<'a, T>>;
586
587    #[inline]
588    fn borrow<'a>(
589        all_storages: &'a AllStorages,
590        all_borrow: Option<SharedBorrow<'a>>,
591        last_run: Option<TrackingTimestamp>,
592        current: TrackingTimestamp,
593    ) -> Result<Self::View<'a>, error::GetStorage> {
594        let view = all_storages.custom_storage_mut_by_id(StorageId::of::<UniqueStorage<T>>())?;
595        let view = ARefMut::map(view, |storage| {
596            storage
597                .as_any_mut()
598                .downcast_mut::<NonSync<UniqueStorage<T>>>()
599                .unwrap()
600        });
601
602        let (unique, borrow) = unsafe { ARefMut::destructure(view) };
603
604        Ok(NonSync(UniqueViewMut {
605            last_insertion: last_run.unwrap_or(unique.last_insert),
606            last_modification: last_run.unwrap_or(unique.last_modification),
607            current,
608            unique,
609            _borrow: Some(borrow),
610            _all_borrow: all_borrow,
611        }))
612    }
613}
614
615#[cfg(feature = "thread_local")]
616impl<T: Unique> Borrow for NonSendSync<UniqueViewMut<'_, T>> {
617    type View<'a> = NonSendSync<UniqueViewMut<'a, T>>;
618
619    #[inline]
620    fn borrow<'a>(
621        all_storages: &'a AllStorages,
622        all_borrow: Option<SharedBorrow<'a>>,
623        last_run: Option<TrackingTimestamp>,
624        current: TrackingTimestamp,
625    ) -> Result<Self::View<'a>, error::GetStorage> {
626        let view = all_storages.custom_storage_mut_by_id(StorageId::of::<UniqueStorage<T>>())?;
627        let view = ARefMut::map(view, |storage| {
628            storage
629                .as_any_mut()
630                .downcast_mut::<NonSendSync<UniqueStorage<T>>>()
631                .unwrap()
632        });
633
634        let (unique, borrow) = unsafe { ARefMut::destructure(view) };
635
636        Ok(NonSendSync(UniqueViewMut {
637            last_insertion: last_run.unwrap_or(unique.last_insert),
638            last_modification: last_run.unwrap_or(unique.last_modification),
639            current,
640            unique,
641            _borrow: Some(borrow),
642            _all_borrow: all_borrow,
643        }))
644    }
645}
646
647impl<T: Borrow> Borrow for Option<T> {
648    type View<'a> = Option<T::View<'a>>;
649
650    #[inline]
651    fn borrow<'a>(
652        all_storages: &'a AllStorages,
653        all_borrow: Option<SharedBorrow<'a>>,
654        last_run: Option<TrackingTimestamp>,
655        current: TrackingTimestamp,
656    ) -> Result<Self::View<'a>, error::GetStorage> {
657        Ok(T::borrow(all_storages, all_borrow, last_run, current).ok())
658    }
659}
660
661macro_rules! impl_borrow {
662    ($(($type: ident, $index: tt))+) => {
663        impl<$($type: Borrow),+> Borrow for ($($type,)+) {
664            type View<'a> = ($($type::View<'a>,)+);
665
666            #[inline]
667            fn borrow<'a>(
668                all_storages: &'a AllStorages,
669                all_borrow: Option<SharedBorrow<'a>>,
670                last_run: Option<TrackingTimestamp>,
671                current: TrackingTimestamp
672            ) -> Result<Self::View<'a>, error::GetStorage> {
673                Ok(($($type::borrow(all_storages, all_borrow.clone(), last_run, current)?,)+))
674            }
675        }
676    }
677}
678
679macro_rules! borrow {
680    ($(($type: ident, $index: tt))*;($type1: ident, $index1: tt) $(($queue_type: ident, $queue_index: tt))*) => {
681        impl_borrow![$(($type, $index))*];
682        borrow![$(($type, $index))* ($type1, $index1); $(($queue_type, $queue_index))*];
683    };
684    ($(($type: ident, $index: tt))*;) => {
685        impl_borrow![$(($type, $index))*];
686    }
687}
688
689#[cfg(not(feature = "extended_tuple"))]
690borrow![(A, 0); (B, 1) (C, 2) (D, 3) (E, 4) (F, 5) (G, 6) (H, 7) (I, 8) (J, 9)];
691#[cfg(feature = "extended_tuple")]
692borrow![
693    (A, 0); (B, 1) (C, 2) (D, 3) (E, 4) (F, 5) (G, 6) (H, 7) (I, 8) (J, 9)
694    (K, 10) (L, 11) (M, 12) (N, 13) (O, 14) (P, 15) (Q, 16) (R, 17) (S, 18) (T, 19)
695    (U, 20) (V, 21) (W, 22) (X, 23) (Y, 24) (Z, 25) (AA, 26) (BB, 27) (CC, 28) (DD, 29)
696    (EE, 30) (FF, 31)
697];