Skip to content

Instantly share code, notes, and snippets.

@dakom
Created February 14, 2023 16:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dakom/dd72217a2c2ac843e438b4ce6adad413 to your computer and use it in GitHub Desktop.
Save dakom/dd72217a2c2ac843e438b4ce6adad413 to your computer and use it in GitHub Desktop.
rust frontend page routing example w/ pure web_sys
use wasm_bindgen::JsValue;
use web_sys::{window, Url};
#[derive(Debug, Clone, PartialEq)]
pub enum Route {
Home,
Profile {
// optional user id
// None means "me"
user_id: Option<String>
},
NotFound,
}
impl Route {
pub fn from_url(url: &str) -> Self {
// get a slice of parts from the url
let url = Url::new(url).unwrap();
let paths = url.pathname();
let mut paths = paths.split('/')
.into_iter()
.skip(1)
.collect::<Vec<_>>();
let paths = paths.as_slice();
// now it's easy-easy, just match on the slice
// can even capture optional parts into variables :)
match paths {
[""] => Self::Home,
["profile", id] => Self::Profile { user_id: Some(id.to_string()) },
["profile"] => Self::Profile { user_id: None },
_ => Self::NotFound,
}
}
}
// the other direction id super easy too
impl ToString for Route {
fn to_string(&self) -> String {
match self {
Route::Home => "/".to_string(),
Route::Profile { user_id } => {
match user_id {
None => "/profile".to_string(),
Some(id) => format!("/profile/{:?}", id)
}
},
Route::NotFound => "404".to_string(),
}
}
}
// icing on the cake
// given a route can easily redirect or push history
impl Route {
pub fn hard_redirect(&self) {
let location = web_sys::window().unwrap().location();
location.set_href(&self.to_string()).unwrap();
}
pub fn push_state(&self) {
let history = web_sys::window().unwrap().history().unwrap();
let _ = history.push_state_with_url(&JsValue::NULL, "", Some(&self.to_string()));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment