Routing
use vertigo::{dom, router::Router};
#[derive(Clone, PartialEq)]
enum Route {
Main,
Post(String),
NotFound(String),
}
impl std::fmt::Display for Route {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Route::Main => write!(f, "/main"),
Route::Post(slug) => write!(f, "/post/{slug}"),
Route::NotFound(x) => write!(f, "{x}"),
}
}
}
impl From<String> for Route {
fn from(value: String) -> Self {
if value == "/main" {
return Self::Main;
} else if value.starts_with("/post") {
if let Some(slug) = value.split('/').nth(1) {
return Self::Post(slug.to_string());
}
}
Self::NotFound(value)
}
}
let routing = Router::new_history_router();
let page = routing.route.render_value(|route| match route {
Route::Main => dom! { <main>"Main Page"</main> },
Route::Post(slug) => dom! { <main>"Post with slug " {slug}</main> },
Route::NotFound(path) => dom! { <main>"Page " {path} " not found"</main> },
});
dom! {
<div>
{page}
</div>
}
Matching against current route
use vertigo::{Computed, dom, router::Router};
#[derive(Clone, PartialEq)]
enum Route {
Main,
Post(String),
NotFound(String),
}
impl Route {
pub fn matches(self, current: &Computed<Self>) -> Computed<bool> {
current.map(move |current| self == current)
}
}
impl std::fmt::Display for Route {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Route::Main => write!(f, "/main"),
Route::Post(slug) => write!(f, "/post/{slug}"),
Route::NotFound(x) => write!(f, "{x}"),
}
}
}
impl From<String> for Route {
fn from(value: String) -> Self {
if value == "/main" {
return Self::Main;
} else if value.starts_with("/post") {
if let Some(slug) = value.split('/').nth(1) {
return Self::Post(slug.to_string());
}
}
Self::NotFound(value)
}
}
let routing = Router::new_history_router();
// Will generate Some(<p>) only if Main is the current route.
let main_page_info = Route::Main.matches(&routing.route)
.render_value_option(|is_active|
is_active.then(|| dom! { <p>"You're in the main menu!"</p> })
);
let page = routing.route.render_value(|route| match route {
Route::Main => dom! { <main>"Main Page"</main> },
Route::Post(slug) => dom! { <main>"Post with slug " {slug}</main> },
Route::NotFound(path) => dom! { <main>"Page " {path} " not found"</main> },
});
dom! {
<div>
{main_page_info}
{page}
</div>
}