1use std::marker::PhantomData;
14
15use yew::prelude::*;
16use yew_router::prelude::*;
17
18#[derive(Clone, Debug)]
25pub struct Navigation<R>
26where
27 R: Routable + Clone + 'static
28{
29 navigator: Option<Navigator>,
30 pub go_back: Callback<()>,
32 pub go_forward: Callback<()>,
34 marker: PhantomData<R>
35}
36
37impl<R> Navigation<R>
38where
39 R: Routable + Clone + 'static
40{
41 pub fn push_callback(&self, route: R) -> Callback<()> {
46 let navigator = self.navigator.clone();
47 Callback::from(move |()| {
48 if let Some(navigator) = &navigator {
49 navigator.push(&route);
50 }
51 })
52 }
53
54 pub fn replace_callback(&self, route: R) -> Callback<()> {
59 let navigator = self.navigator.clone();
60 Callback::from(move |()| {
61 if let Some(navigator) = &navigator {
62 navigator.replace(&route);
63 }
64 })
65 }
66
67 #[must_use]
69 pub fn go_callback(&self, delta: isize) -> Callback<()> {
70 let navigator = self.navigator.clone();
71 Callback::from(move |()| {
72 if let Some(navigator) = &navigator {
73 navigator.go(delta);
74 }
75 })
76 }
77}
78
79#[hook]
108pub fn use_navigation<R>() -> Navigation<R>
109where
110 R: Routable + Clone + 'static
111{
112 let navigator = use_navigator();
113
114 let go_back = {
115 let navigator = navigator.clone();
116 Callback::from(move |()| {
117 if let Some(navigator) = &navigator {
118 navigator.back();
119 }
120 })
121 };
122
123 let go_forward = {
124 let navigator = navigator.clone();
125 Callback::from(move |()| {
126 if let Some(navigator) = &navigator {
127 navigator.forward();
128 }
129 })
130 };
131
132 Navigation {
133 navigator,
134 go_back,
135 go_forward,
136 marker: PhantomData
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use std::marker::PhantomData;
143
144 use super::*;
145
146 #[test]
147 fn navigation_struct_creation() {
148 #[derive(Clone, PartialEq, Debug, Routable)]
149 enum TestRoute {
150 #[at("/test")]
151 Test,
152 #[at("/")]
153 Home
154 }
155
156 let nav = Navigation::<TestRoute> {
157 go_back: Callback::from(|()| {}),
158 go_forward: Callback::from(|()| {}),
159 navigator: None,
160 marker: PhantomData
161 };
162
163 let _ = nav.go_back;
164 let _ = nav.go_forward;
165 }
166
167 #[test]
168 fn navigation_clone() {
169 #[derive(Clone, PartialEq, Debug, Routable)]
170 enum TestRoute {
171 #[at("/test")]
172 Test
173 }
174
175 let nav1 = Navigation::<TestRoute> {
176 go_back: Callback::from(|()| {}),
177 go_forward: Callback::from(|()| {}),
178 navigator: None,
179 marker: PhantomData
180 };
181
182 let nav2 = nav1;
183 let _ = nav2.go_back;
184 let _ = nav2.go_forward;
185 }
186
187 #[test]
188 fn navigation_debug() {
189 #[derive(Clone, PartialEq, Debug, Routable)]
190 enum TestRoute {
191 #[at("/test")]
192 Test
193 }
194
195 let nav = Navigation::<TestRoute> {
196 go_back: Callback::from(|()| {}),
197 go_forward: Callback::from(|()| {}),
198 navigator: None,
199 marker: PhantomData
200 };
201
202 let debug_str = format!("{nav:?}");
203 assert!(debug_str.contains("Navigation"));
204 }
205
206 #[test]
207 fn navigation_partial_eq() {
208 #[derive(Clone, PartialEq, Debug, Routable)]
209 enum TestRoute {
210 #[at("/test")]
211 Test
212 }
213
214 let nav1 = Navigation::<TestRoute> {
215 go_back: Callback::from(|()| {}),
216 go_forward: Callback::from(|()| {}),
217 navigator: None,
218 marker: PhantomData
219 };
220 let nav2 = nav1;
221 let _ = nav1.go_back;
222 let _ = nav2.go_back;
223 }
224
225 #[test]
226 fn navigation_push_callback() {
227 #[derive(Clone, PartialEq, Debug, Routable)]
228 enum TestRoute {
229 #[at("/")]
230 Home
231 }
232
233 let nav = Navigation::<TestRoute> {
234 go_back: Callback::from(|()| {}),
235 go_forward: Callback::from(|()| {}),
236 navigator: None,
237 marker: PhantomData
238 };
239 let _ = nav.push_callback(TestRoute::Home);
240 }
241
242 #[test]
243 fn navigation_replace_callback() {
244 #[derive(Clone, PartialEq, Debug, Routable)]
245 enum TestRoute {
246 #[at("/")]
247 Home
248 }
249
250 let nav = Navigation::<TestRoute> {
251 go_back: Callback::from(|()| {}),
252 go_forward: Callback::from(|()| {}),
253 navigator: None,
254 marker: PhantomData
255 };
256 let _ = nav.replace_callback(TestRoute::Home);
257 }
258
259 #[test]
260 fn navigation_go_callback() {
261 #[derive(Clone, PartialEq, Debug, Routable)]
262 enum TestRoute {
263 #[at("/")]
264 Home
265 }
266
267 let nav = Navigation::<TestRoute> {
268 go_back: Callback::from(|()| {}),
269 go_forward: Callback::from(|()| {}),
270 navigator: None,
271 marker: PhantomData
272 };
273 let _ = nav.go_callback(-1);
274 }
275
276 #[test]
277 fn navigation_go_callback_with_positive_delta() {
278 #[derive(Clone, PartialEq, Debug, Routable)]
279 enum TestRoute {
280 #[at("/")]
281 Home
282 }
283
284 let nav = Navigation::<TestRoute> {
285 go_back: Callback::from(|()| {}),
286 go_forward: Callback::from(|()| {}),
287 navigator: None,
288 marker: PhantomData
289 };
290 let callback = nav.go_callback(1);
291 let _ = callback;
292 }
293
294 #[test]
295 fn navigation_go_callback_with_zero_delta() {
296 #[derive(Clone, PartialEq, Debug, Routable)]
297 enum TestRoute {
298 #[at("/")]
299 Home
300 }
301
302 let nav = Navigation::<TestRoute> {
303 go_back: Callback::from(|()| {}),
304 go_forward: Callback::from(|()| {}),
305 navigator: None,
306 marker: PhantomData
307 };
308 let callback = nav.go_callback(0);
309 let _ = callback;
310 }
311
312 #[test]
313 fn navigation_go_callback_with_large_negative_delta() {
314 #[derive(Clone, PartialEq, Debug, Routable)]
315 enum TestRoute {
316 #[at("/")]
317 Home
318 }
319
320 let nav = Navigation::<TestRoute> {
321 go_back: Callback::from(|()| {}),
322 go_forward: Callback::from(|()| {}),
323 navigator: None,
324 marker: PhantomData
325 };
326 let callback = nav.go_callback(-10);
327 let _ = callback;
328 }
329
330 #[test]
331 fn navigation_go_callback_with_large_positive_delta() {
332 #[derive(Clone, PartialEq, Debug, Routable)]
333 enum TestRoute {
334 #[at("/")]
335 Home
336 }
337
338 let nav = Navigation::<TestRoute> {
339 go_back: Callback::from(|()| {}),
340 go_forward: Callback::from(|()| {}),
341 navigator: None,
342 marker: PhantomData
343 };
344 let callback = nav.go_callback(10);
345 let _ = callback;
346 }
347
348 #[test]
349 fn navigation_push_callback_with_struct_route() {
350 #[derive(Clone, PartialEq, Debug, Routable)]
351 enum TestRoute {
352 #[at("/users/:id")]
353 User { id: String }
354 }
355
356 let nav = Navigation::<TestRoute> {
357 go_back: Callback::from(|()| {}),
358 go_forward: Callback::from(|()| {}),
359 navigator: None,
360 marker: PhantomData
361 };
362
363 let route = TestRoute::User {
364 id: "123".to_string()
365 };
366 let callback = nav.push_callback(route);
367 let _ = callback;
368 }
369
370 #[test]
371 fn navigation_push_callback_with_tuple_route() {
372 #[derive(Clone, PartialEq, Debug, Routable)]
373 enum TestRoute {
374 #[at("/posts/:year")]
375 Post { year: u32 }
376 }
377
378 let nav = Navigation::<TestRoute> {
379 go_back: Callback::from(|()| {}),
380 go_forward: Callback::from(|()| {}),
381 navigator: None,
382 marker: PhantomData
383 };
384
385 let route = TestRoute::Post {
386 year: 2024
387 };
388 let callback = nav.push_callback(route);
389 let _ = callback;
390 }
391
392 #[test]
393 fn navigation_replace_callback_with_struct_route() {
394 #[derive(Clone, PartialEq, Debug, Routable)]
395 enum TestRoute {
396 #[at("/settings/:section")]
397 Settings { section: String }
398 }
399
400 let nav = Navigation::<TestRoute> {
401 go_back: Callback::from(|()| {}),
402 go_forward: Callback::from(|()| {}),
403 navigator: None,
404 marker: PhantomData
405 };
406
407 let route = TestRoute::Settings {
408 section: "profile".to_string()
409 };
410 let callback = nav.replace_callback(route);
411 let _ = callback;
412 }
413
414 #[test]
415 fn navigation_replace_callback_with_tuple_route() {
416 #[derive(Clone, PartialEq, Debug, Routable)]
417 enum TestRoute {
418 #[at("/api/:version")]
419 Api { version: u32 }
420 }
421
422 let nav = Navigation::<TestRoute> {
423 go_back: Callback::from(|()| {}),
424 go_forward: Callback::from(|()| {}),
425 navigator: None,
426 marker: PhantomData
427 };
428
429 let route = TestRoute::Api {
430 version: 1
431 };
432 let callback = nav.replace_callback(route);
433 let _ = callback;
434 }
435
436 #[test]
437 fn navigation_callbacks_are_distinct() {
438 #[derive(Clone, PartialEq, Debug, Routable)]
439 enum TestRoute {
440 #[at("/")]
441 Home,
442 #[at("/about")]
443 About
444 }
445
446 let nav = Navigation::<TestRoute> {
447 go_back: Callback::from(|()| {}),
448 go_forward: Callback::from(|()| {}),
449 navigator: None,
450 marker: PhantomData
451 };
452
453 let push_callback = nav.push_callback(TestRoute::Home);
454 let replace_callback = nav.replace_callback(TestRoute::About);
455 let go_callback = nav.go_callback(-1);
456
457 let _ = push_callback;
458 let _ = replace_callback;
459 let _ = go_callback;
460 }
461
462 #[test]
463 fn navigation_multiple_callbacks_same_route() {
464 #[derive(Clone, PartialEq, Debug, Routable)]
465 enum TestRoute {
466 #[at("/")]
467 Home
468 }
469
470 let nav = Navigation::<TestRoute> {
471 go_back: Callback::from(|()| {}),
472 go_forward: Callback::from(|()| {}),
473 navigator: None,
474 marker: PhantomData
475 };
476
477 let callback1 = nav.push_callback(TestRoute::Home);
478 let callback2 = nav.push_callback(TestRoute::Home);
479 let callback3 = nav.push_callback(TestRoute::Home);
480
481 let _ = callback1;
482 let _ = callback2;
483 let _ = callback3;
484 }
485
486 #[test]
487 fn navigation_callbacks_with_complex_route() {
488 #[derive(Clone, PartialEq, Debug, Routable)]
489 enum ComplexRoute {
490 #[at("/")]
491 Home,
492 #[at("/users")]
493 Users,
494 #[at("/admin")]
495 Admin,
496 #[at("/date")]
497 Date
498 }
499
500 let nav = Navigation::<ComplexRoute> {
501 go_back: Callback::from(|()| {}),
502 go_forward: Callback::from(|()| {}),
503 navigator: None,
504 marker: PhantomData
505 };
506
507 let _ = nav.push_callback(ComplexRoute::Home);
508 let _ = nav.push_callback(ComplexRoute::Users);
509 let _ = nav.push_callback(ComplexRoute::Admin);
510 let _ = nav.push_callback(ComplexRoute::Date);
511 }
512
513 #[test]
514 fn navigation_callbacks_preserve_route_data() {
515 #[derive(Clone, PartialEq, Debug, Routable)]
516 enum TestRoute {
517 #[at("/search/:query")]
518 Search { query: String }
519 }
520
521 let nav = Navigation::<TestRoute> {
522 go_back: Callback::from(|()| {}),
523 go_forward: Callback::from(|()| {}),
524 navigator: None,
525 marker: PhantomData
526 };
527
528 let query = "rust programming".to_string();
529 let route = TestRoute::Search {
530 query: query.clone()
531 };
532 let _callback = nav.push_callback(route);
533
534 assert_eq!(query, "rust programming");
535 }
536
537 #[test]
538 fn navigation_go_back_callback_exists() {
539 #[derive(Clone, PartialEq, Debug, Routable)]
540 enum TestRoute {
541 #[at("/")]
542 Home
543 }
544
545 let nav = Navigation::<TestRoute> {
546 go_back: Callback::from(|()| {}),
547 go_forward: Callback::from(|()| {}),
548 navigator: None,
549 marker: PhantomData
550 };
551
552 let _ = nav.go_back;
553 }
554
555 #[test]
556 fn navigation_go_forward_callback_exists() {
557 #[derive(Clone, PartialEq, Debug, Routable)]
558 enum TestRoute {
559 #[at("/")]
560 Home
561 }
562
563 let nav = Navigation::<TestRoute> {
564 go_back: Callback::from(|()| {}),
565 go_forward: Callback::from(|()| {}),
566 navigator: None,
567 marker: PhantomData
568 };
569
570 let _ = nav.go_forward;
571 }
572
573 #[test]
574 fn navigation_struct_with_multiple_variants() {
575 #[derive(Clone, PartialEq, Debug, Routable)]
576 enum MultiVariantRoute {
577 #[at("/")]
578 Home,
579 #[at("/about")]
580 About,
581 #[at("/contact")]
582 Contact,
583 #[at("/products")]
584 Products,
585 #[at("/services")]
586 Services,
587 #[at("/blog")]
588 Blog,
589 #[at("/faq")]
590 Faq
591 }
592
593 let nav = Navigation::<MultiVariantRoute> {
594 go_back: Callback::from(|()| {}),
595 go_forward: Callback::from(|()| {}),
596 navigator: None,
597 marker: PhantomData
598 };
599
600 let _ = nav.push_callback(MultiVariantRoute::Home);
601 let _ = nav.push_callback(MultiVariantRoute::About);
602 let _ = nav.push_callback(MultiVariantRoute::Contact);
603 let _ = nav.push_callback(MultiVariantRoute::Products);
604 let _ = nav.push_callback(MultiVariantRoute::Services);
605 let _ = nav.push_callback(MultiVariantRoute::Blog);
606 let _ = nav.push_callback(MultiVariantRoute::Faq);
607 }
608
609 #[test]
610 fn navigation_go_callback_edge_cases() {
611 #[derive(Clone, PartialEq, Debug, Routable)]
612 enum TestRoute {
613 #[at("/")]
614 Home
615 }
616
617 let nav = Navigation::<TestRoute> {
618 go_back: Callback::from(|()| {}),
619 go_forward: Callback::from(|()| {}),
620 navigator: None,
621 marker: PhantomData
622 };
623
624 let min_delta = nav.go_callback(isize::MIN);
625 let max_delta = nav.go_callback(isize::MAX);
626 let neg_one = nav.go_callback(-1);
627 let pos_one = nav.go_callback(1);
628
629 let _ = min_delta;
630 let _ = max_delta;
631 let _ = neg_one;
632 let _ = pos_one;
633 }
634
635 #[test]
636 fn navigation_callbacks_with_empty_string_route() {
637 #[derive(Clone, PartialEq, Debug, Routable)]
638 enum TestRoute {
639 #[at("/item/:name")]
640 Item { name: String }
641 }
642
643 let nav = Navigation::<TestRoute> {
644 go_back: Callback::from(|()| {}),
645 go_forward: Callback::from(|()| {}),
646 navigator: None,
647 marker: PhantomData
648 };
649
650 let route = TestRoute::Item {
651 name: String::new()
652 };
653 let callback = nav.push_callback(route);
654 let _ = callback;
655 }
656
657 #[test]
658 fn navigation_callbacks_with_special_characters() {
659 #[derive(Clone, PartialEq, Debug, Routable)]
660 enum TestRoute {
661 #[at("/tag/:name")]
662 Tag { name: String }
663 }
664
665 let nav = Navigation::<TestRoute> {
666 go_back: Callback::from(|()| {}),
667 go_forward: Callback::from(|()| {}),
668 navigator: None,
669 marker: PhantomData
670 };
671
672 let route = TestRoute::Tag {
673 name: "rust-lang".to_string()
674 };
675 let callback = nav.push_callback(route);
676 let _ = callback;
677 }
678
679 #[test]
680 fn navigation_callbacks_with_unicode() {
681 #[derive(Clone, PartialEq, Debug, Routable)]
682 enum TestRoute {
683 #[at("/emoji/:emoji")]
684 Emoji { emoji: String }
685 }
686
687 let nav = Navigation::<TestRoute> {
688 go_back: Callback::from(|()| {}),
689 go_forward: Callback::from(|()| {}),
690 navigator: None,
691 marker: PhantomData
692 };
693
694 let route = TestRoute::Emoji {
695 emoji: "🦀".to_string()
696 };
697 let callback = nav.push_callback(route);
698 let _ = callback;
699 }
700
701 #[test]
702 fn navigation_callbacks_with_numbers() {
703 #[derive(Clone, PartialEq, Debug, Routable)]
704 enum TestRoute {
705 #[at("/number/:num")]
706 Number { num: u64 }
707 }
708
709 let nav = Navigation::<TestRoute> {
710 go_back: Callback::from(|()| {}),
711 go_forward: Callback::from(|()| {}),
712 navigator: None,
713 marker: PhantomData
714 };
715
716 let route = TestRoute::Number {
717 num: 0
718 };
719 let callback = nav.push_callback(route);
720 let _ = callback;
721
722 let route = TestRoute::Number {
723 num: u64::MAX
724 };
725 let callback = nav.push_callback(route);
726 let _ = callback;
727 }
728
729 #[test]
730 fn navigation_struct_debug_format() {
731 #[derive(Clone, PartialEq, Debug, Routable)]
732 enum TestRoute {
733 #[at("/")]
734 Home
735 }
736
737 let nav = Navigation::<TestRoute> {
738 go_back: Callback::from(|()| {}),
739 go_forward: Callback::from(|()| {}),
740 navigator: None,
741 marker: PhantomData
742 };
743
744 let debug_str = format!("{nav:?}");
745 assert!(debug_str.contains("Navigation"));
746 assert!(debug_str.contains("go_back"));
747 assert!(debug_str.contains("go_forward"));
748 }
749
750 #[test]
751 fn navigation_callbacks_chainability() {
752 #[derive(Clone, PartialEq, Debug, Routable)]
753 enum TestRoute {
754 #[at("/")]
755 Home,
756 #[at("/step1")]
757 Step1,
758 #[at("/step2")]
759 Step2,
760 #[at("/step3")]
761 Step3
762 }
763
764 let nav = Navigation::<TestRoute> {
765 go_back: Callback::from(|()| {}),
766 go_forward: Callback::from(|()| {}),
767 navigator: None,
768 marker: PhantomData
769 };
770
771 let step1_callback = nav.push_callback(TestRoute::Step1);
772 let step2_callback = nav.push_callback(TestRoute::Step2);
773 let step3_callback = nav.push_callback(TestRoute::Step3);
774 let back_callback = nav.go_callback(-1);
775
776 let _ = step1_callback;
777 let _ = step2_callback;
778 let _ = step3_callback;
779 let _ = back_callback;
780 }
781
782 #[test]
783 fn navigation_replace_vs_push_same_route() {
784 #[derive(Clone, PartialEq, Debug, Routable)]
785 enum TestRoute {
786 #[at("/")]
787 Home
788 }
789
790 let nav = Navigation::<TestRoute> {
791 go_back: Callback::from(|()| {}),
792 go_forward: Callback::from(|()| {}),
793 navigator: None,
794 marker: PhantomData
795 };
796
797 let push_cb = nav.push_callback(TestRoute::Home);
798 let replace_cb = nav.replace_callback(TestRoute::Home);
799
800 let _ = push_cb;
801 let _ = replace_cb;
802 }
803
804 #[test]
805 fn navigation_callbacks_with_nested_route_params() {
806 #[derive(Clone, PartialEq, Debug, Routable)]
807 enum TestRoute {
808 #[at("/org/:org_id/team/:team_id/member/:member_id")]
809 Member {
810 org_id: String,
811 team_id: String,
812 member_id: String
813 }
814 }
815
816 let nav = Navigation::<TestRoute> {
817 go_back: Callback::from(|()| {}),
818 go_forward: Callback::from(|()| {}),
819 navigator: None,
820 marker: PhantomData
821 };
822
823 let route = TestRoute::Member {
824 org_id: "org1".to_string(),
825 team_id: "team1".to_string(),
826 member_id: "member1".to_string()
827 };
828 let callback = nav.push_callback(route);
829 let _ = callback;
830 }
831
832 #[test]
833 fn navigation_callbacks_with_optional_like_params() {
834 #[derive(Clone, PartialEq, Debug, Routable)]
835 enum TestRoute {
836 #[at("/filter/:min/:max")]
837 Filter { min: u32, max: u32 }
838 }
839
840 let nav = Navigation::<TestRoute> {
841 go_back: Callback::from(|()| {}),
842 go_forward: Callback::from(|()| {}),
843 navigator: None,
844 marker: PhantomData
845 };
846
847 let route = TestRoute::Filter {
848 min: 0, max: 100
849 };
850 let callback = nav.push_callback(route);
851 let _ = callback;
852 }
853
854 #[test]
855 fn navigation_go_callback_returns_valid_callback() {
856 #[derive(Clone, PartialEq, Debug, Routable)]
857 enum TestRoute {
858 #[at("/")]
859 Home
860 }
861
862 let nav = Navigation::<TestRoute> {
863 go_back: Callback::from(|()| {}),
864 go_forward: Callback::from(|()| {}),
865 navigator: None,
866 marker: PhantomData
867 };
868
869 let callback = nav.go_callback(-5);
870 let _ = callback;
871 }
872
873 #[test]
874 fn navigation_struct_fields_accessible() {
875 #[derive(Clone, PartialEq, Debug, Routable)]
876 enum TestRoute {
877 #[at("/")]
878 Home
879 }
880
881 let nav = Navigation::<TestRoute> {
882 go_back: Callback::from(|()| {}),
883 go_forward: Callback::from(|()| {}),
884 navigator: None,
885 marker: PhantomData
886 };
887
888 let _nav_back = &nav.go_back;
889 let _nav_forward = &nav.go_forward;
890 let _ = nav.marker;
891 }
892
893 #[test]
894 fn navigation_with_multiple_routable_types() {
895 #[derive(Clone, PartialEq, Debug, Routable)]
896 enum Route1 {
897 #[at("/")]
898 Home
899 }
900
901 #[derive(Clone, PartialEq, Debug, Routable)]
902 enum Route2 {
903 #[at("/")]
904 Page
905 }
906
907 let nav1 = Navigation::<Route1> {
908 go_back: Callback::from(|()| {}),
909 go_forward: Callback::from(|()| {}),
910 navigator: None,
911 marker: PhantomData
912 };
913
914 let nav2 = Navigation::<Route2> {
915 go_back: Callback::from(|()| {}),
916 go_forward: Callback::from(|()| {}),
917 navigator: None,
918 marker: PhantomData
919 };
920
921 let _ = nav1.push_callback(Route1::Home);
922 let _ = nav2.push_callback(Route2::Page);
923 }
924
925 #[test]
926 fn navigation_push_callback_multiple_times() {
927 #[derive(Clone, PartialEq, Debug, Routable)]
928 enum TestRoute {
929 #[at("/")]
930 Home
931 }
932
933 let nav = Navigation::<TestRoute> {
934 go_back: Callback::from(|()| {}),
935 go_forward: Callback::from(|()| {}),
936 navigator: None,
937 marker: PhantomData
938 };
939
940 let _ = nav.push_callback(TestRoute::Home);
941 let _ = nav.push_callback(TestRoute::Home);
942 let _ = nav.push_callback(TestRoute::Home);
943 }
944
945 #[test]
946 fn navigation_replace_callback_multiple_times() {
947 #[derive(Clone, PartialEq, Debug, Routable)]
948 enum TestRoute {
949 #[at("/")]
950 Home
951 }
952
953 let nav = Navigation::<TestRoute> {
954 go_back: Callback::from(|()| {}),
955 go_forward: Callback::from(|()| {}),
956 navigator: None,
957 marker: PhantomData
958 };
959
960 let _ = nav.replace_callback(TestRoute::Home);
961 let _ = nav.replace_callback(TestRoute::Home);
962 let _ = nav.replace_callback(TestRoute::Home);
963 }
964}