query_segments.rs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. //! Example: Url query segments usage
  2. //! ------------------------------------
  3. //!
  4. //! This example shows how to access and use multiple query segments present in an url on the web.
  5. //!
  6. //! Run `dx serve` and navigate to `http://localhost:8080/blog?name=John&surname=Doe`
  7. use dioxus::prelude::*;
  8. use dioxus::router::prelude::*;
  9. use std::fmt::Display;
  10. #[derive(Routable, Clone)]
  11. #[rustfmt::skip]
  12. enum Route {
  13. // segments that start with ?:.. are query segments that capture the entire query
  14. #[route("/blog?:..query_params")]
  15. BlogPost {
  16. // You must include query segments in child variants
  17. query_params: ManualBlogQuerySegments,
  18. },
  19. // segments that follow the ?:field&:other_field syntax are query segments that follow the standard url query syntax
  20. #[route("/autoblog?:name&:surname")]
  21. AutomaticBlogPost {
  22. name: String,
  23. surname: String,
  24. },
  25. }
  26. #[derive(Debug, Clone, PartialEq)]
  27. struct ManualBlogQuerySegments {
  28. name: String,
  29. surname: String,
  30. }
  31. /// The display impl needs to display the query in a way that can be parsed:
  32. impl Display for ManualBlogQuerySegments {
  33. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  34. write!(f, "name={}&surname={}", self.name, self.surname)
  35. }
  36. }
  37. /// The query segment is anything that implements <https://docs.rs/dioxus-router/latest/dioxus::router/routable/trait.FromQuery.html>. You can implement that trait for a struct if you want to parse multiple query parameters.
  38. impl FromQuery for ManualBlogQuerySegments {
  39. fn from_query(query: &str) -> Self {
  40. let mut name = None;
  41. let mut surname = None;
  42. let pairs = form_urlencoded::parse(query.as_bytes());
  43. pairs.for_each(|(key, value)| {
  44. if key == "name" {
  45. name = Some(value.clone().into());
  46. }
  47. if key == "surname" {
  48. surname = Some(value.clone().into());
  49. }
  50. });
  51. Self {
  52. name: name.unwrap(),
  53. surname: surname.unwrap(),
  54. }
  55. }
  56. }
  57. #[component]
  58. fn BlogPost(query_params: ManualBlogQuerySegments) -> Element {
  59. rsx! {
  60. div { "This is your blogpost with a query segment:" }
  61. div { "{query_params:?}" }
  62. }
  63. }
  64. #[component]
  65. fn AutomaticBlogPost(name: String, surname: String) -> Element {
  66. rsx! {
  67. div { "This is your blogpost with a query segment:" }
  68. div { "name={name}&surname={surname}" }
  69. }
  70. }
  71. #[component]
  72. fn App() -> Element {
  73. rsx! { Router::<Route> {} }
  74. }
  75. fn main() {
  76. launch(App);
  77. }