macro.rs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #![allow(non_snake_case)]
  2. use dioxus::prelude::*;
  3. use dioxus_router_core::*;
  4. use dioxus_router_macro::*;
  5. use std::str::FromStr;
  6. #[inline_props]
  7. fn Route1(cx: Scope, dynamic: String) -> Element {
  8. render! {
  9. div{
  10. "Route1: {dynamic}"
  11. }
  12. }
  13. }
  14. #[inline_props]
  15. fn Route2(cx: Scope) -> Element {
  16. render! {
  17. div{
  18. "Route2"
  19. }
  20. }
  21. }
  22. #[inline_props]
  23. fn Route3(cx: Scope, dynamic: u32) -> Element {
  24. render! {
  25. div{
  26. "Route3: {dynamic}"
  27. }
  28. }
  29. }
  30. #[inline_props]
  31. fn Route4(cx: Scope, number1: u32, number2: u32) -> Element {
  32. render! {
  33. div{
  34. "Route4: {number1} {number2}"
  35. }
  36. }
  37. }
  38. #[inline_props]
  39. fn Route5(cx: Scope, query: String) -> Element {
  40. render! {
  41. div{
  42. "Route5: {query}"
  43. }
  44. }
  45. }
  46. #[inline_props]
  47. fn Route6(cx: Scope, extra: Vec<String>) -> Element {
  48. render! {
  49. div{
  50. "Route5: {extra:?}"
  51. }
  52. }
  53. }
  54. #[inline_props]
  55. fn Nested(cx: Scope, nested: String) -> Element {
  56. render! {
  57. div{
  58. "Nested: {nested:?}"
  59. }
  60. }
  61. }
  62. #[rustfmt::skip]
  63. #[routable]
  64. #[derive(Clone, Debug, PartialEq)]
  65. enum Route {
  66. #[route("/(dynamic)" Route1)]
  67. Route1 { dynamic: String },
  68. #[nest("/(nested)" nested { nested: String } Nested)]
  69. #[route("/" Route2)]
  70. Route2 {},
  71. // #[redirect("/(dynamic)/hello_world")]
  72. #[route("/(dynamic)" Route3)]
  73. Route3 { dynamic: u32 },
  74. #[end_nest]
  75. #[route("/(number1)/(number2)" Route4)]
  76. Route4 { number1: u32, number2: u32 },
  77. #[route("/?(query)" Route5)]
  78. Route5 { query: String },
  79. #[route("/(...extra)" Route6)]
  80. Route6 { extra: Vec<String> },
  81. }
  82. #[test]
  83. fn display_works() {
  84. let route = Route::Route1 {
  85. dynamic: "hello".to_string(),
  86. };
  87. assert_eq!(route.to_string(), "/hello");
  88. let route = Route::Route3 { dynamic: 1234 };
  89. assert_eq!(route.to_string(), "/hello_world/1234");
  90. let route = Route::Route1 {
  91. dynamic: "hello_world2".to_string(),
  92. };
  93. assert_eq!(route.to_string(), "/hello_world2");
  94. let route = Route::Route4 {
  95. number1: 1234,
  96. number2: 5678,
  97. };
  98. assert_eq!(route.to_string(), "/1234/5678");
  99. let route = Route::Route5 {
  100. query: "hello".to_string(),
  101. };
  102. assert_eq!(route.to_string(), "/?hello");
  103. let route = Route::Route6 {
  104. extra: vec!["hello".to_string(), "world".to_string()],
  105. };
  106. assert_eq!(route.to_string(), "/hello/world");
  107. }
  108. #[test]
  109. fn from_string_works() {
  110. let w = "/hello";
  111. assert_eq!(
  112. Route::from_str(w),
  113. Ok(Route::Route1 {
  114. dynamic: "hello".to_string()
  115. })
  116. );
  117. let w = "/hello/";
  118. assert_eq!(
  119. Route::from_str(w),
  120. Ok(Route::Route1 {
  121. dynamic: "hello".to_string()
  122. })
  123. );
  124. let w = "/hello_world/1234";
  125. assert_eq!(Route::from_str(w), Ok(Route::Route3 { dynamic: 1234 }));
  126. let w = "/hello_world/1234/";
  127. assert_eq!(Route::from_str(w), Ok(Route::Route3 { dynamic: 1234 }));
  128. let w = "/hello_world2";
  129. assert_eq!(
  130. Route::from_str(w),
  131. Ok(Route::Route1 {
  132. dynamic: "hello_world2".to_string()
  133. })
  134. );
  135. let w = "/?x=1234&y=hello";
  136. assert_eq!(
  137. Route::from_str(w),
  138. Ok(Route::Route5 {
  139. query: "x=1234&y=hello".to_string()
  140. })
  141. );
  142. let w = "/hello_world/hello_world/hello_world";
  143. assert_eq!(
  144. Route::from_str(w),
  145. Ok(Route::Route6 {
  146. extra: vec![
  147. "hello_world".to_string(),
  148. "hello_world".to_string(),
  149. "hello_world".to_string()
  150. ]
  151. })
  152. );
  153. }
  154. #[test]
  155. fn round_trip() {
  156. // Route1
  157. let string = "hello_world2";
  158. let route = Route::Route1 {
  159. dynamic: string.to_string(),
  160. };
  161. assert_eq!(Route::from_str(&route.to_string()), Ok(route));
  162. // Route2
  163. for num in 0..100 {
  164. let route = Route::Route3 { dynamic: num };
  165. assert_eq!(Route::from_str(&route.to_string()), Ok(route));
  166. }
  167. // Route3
  168. for num1 in 0..100 {
  169. for num2 in 0..100 {
  170. let route = Route::Route4 {
  171. number1: num1,
  172. number2: num2,
  173. };
  174. assert_eq!(Route::from_str(&route.to_string()), Ok(route));
  175. }
  176. }
  177. // Route4
  178. let string = "x=1234&y=hello";
  179. let route = Route::Route5 {
  180. query: string.to_string(),
  181. };
  182. assert_eq!(Route::from_str(&route.to_string()), Ok(route));
  183. // Route5
  184. let route = Route::Route6 {
  185. extra: vec![
  186. "hello_world".to_string(),
  187. "hello_world".to_string(),
  188. "hello_world".to_string(),
  189. ],
  190. };
  191. assert_eq!(Route::from_str(&route.to_string()), Ok(route));
  192. }
  193. fn main() {}