Created
February 14, 2023 16:54
-
-
Save dakom/dd72217a2c2ac843e438b4ce6adad413 to your computer and use it in GitHub Desktop.
rust frontend page routing example w/ pure web_sys
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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