macro.rs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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. #[route("/:number1/:number2" Route4)]
  69. Route4 { number1: u32, number2: u32 },
  70. #[nest("/:nested" nested { nested: String } Nested)]
  71. #[route("/" Route2)]
  72. Route2 {},
  73. // #[redirect("/:dynamic/hello_world")]
  74. #[route("/:dynamic" Route3)]
  75. Route3 { dynamic: u32 },
  76. #[end_nest]
  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 {
  89. nested: "hello_world".to_string(),
  90. dynamic: 1234,
  91. };
  92. assert_eq!(route.to_string(), "/hello_world/1234");
  93. let route = Route::Route1 {
  94. dynamic: "hello_world2".to_string(),
  95. };
  96. assert_eq!(route.to_string(), "/hello_world2");
  97. let route = Route::Route4 {
  98. number1: 1234,
  99. number2: 5678,
  100. };
  101. assert_eq!(route.to_string(), "/1234/5678");
  102. let route = Route::Route5 {
  103. query: "hello".to_string(),
  104. };
  105. assert_eq!(route.to_string(), "/?hello");
  106. let route = Route::Route6 {
  107. extra: vec!["hello".to_string(), "world".to_string()],
  108. };
  109. assert_eq!(route.to_string(), "/hello/world");
  110. }
  111. #[test]
  112. fn from_string_works() {
  113. let w = "/hello";
  114. assert_eq!(
  115. Route::from_str(w),
  116. Ok(Route::Route1 {
  117. dynamic: "hello".to_string()
  118. })
  119. );
  120. let w = "/hello/";
  121. assert_eq!(
  122. Route::from_str(w),
  123. Ok(Route::Route1 {
  124. dynamic: "hello".to_string()
  125. })
  126. );
  127. let w = "/hello_world/1234";
  128. assert_eq!(
  129. Route::from_str(w),
  130. Ok(Route::Route3 {
  131. nested: "hello_world".to_string(),
  132. dynamic: 1234
  133. })
  134. );
  135. let w = "/hello_world/1234/";
  136. assert_eq!(
  137. Route::from_str(w),
  138. Ok(Route::Route3 {
  139. nested: "hello_world".to_string(),
  140. dynamic: 1234
  141. })
  142. );
  143. let w = "/hello_world2";
  144. assert_eq!(
  145. Route::from_str(w),
  146. Ok(Route::Route1 {
  147. dynamic: "hello_world2".to_string()
  148. })
  149. );
  150. let w = "/?x=1234&y=hello";
  151. assert_eq!(
  152. Route::from_str(w),
  153. Ok(Route::Route5 {
  154. query: "x=1234&y=hello".to_string()
  155. })
  156. );
  157. let w = "/hello_world/hello_world/hello_world";
  158. assert_eq!(
  159. Route::from_str(w),
  160. Ok(Route::Route6 {
  161. extra: vec![
  162. "hello_world".to_string(),
  163. "hello_world".to_string(),
  164. "hello_world".to_string()
  165. ]
  166. })
  167. );
  168. }
  169. #[test]
  170. fn round_trip() {
  171. // Route1
  172. let string = "hello_world2";
  173. let route = Route::Route1 {
  174. dynamic: string.to_string(),
  175. };
  176. assert_eq!(Route::from_str(&route.to_string()), Ok(route));
  177. // Route2
  178. for num1 in 0..100 {
  179. for num2 in 0..100 {
  180. let route = Route::Route3 {
  181. nested: format!("number{num1}"),
  182. dynamic: num2,
  183. };
  184. assert_eq!(Route::from_str(&route.to_string()), Ok(route));
  185. }
  186. }
  187. // Route3
  188. for num1 in 0..100 {
  189. for num2 in 0..100 {
  190. let route = Route::Route4 {
  191. number1: num1,
  192. number2: num2,
  193. };
  194. assert_eq!(Route::from_str(&route.to_string()), Ok(route));
  195. }
  196. }
  197. // Route4
  198. let string = "x=1234&y=hello";
  199. let route = Route::Route5 {
  200. query: string.to_string(),
  201. };
  202. assert_eq!(Route::from_str(&route.to_string()), Ok(route));
  203. // Route5
  204. let route = Route::Route6 {
  205. extra: vec![
  206. "hello_world".to_string(),
  207. "hello_world".to_string(),
  208. "hello_world".to_string(),
  209. ],
  210. };
  211. assert_eq!(Route::from_str(&route.to_string()), Ok(route));
  212. }
  213. fn main() {}