Intigrate macro with router hooks and components

This commit is contained in:
Evan Almloff committed 2023-05-22 16:42:32 -05:00
1 parent ef6551a6cd
commit e4b8fbfafe
37 files changed
+1442 -3009

No files matched your search

+126
View File
@@ -0,0 +1,126 @@
//! # Routable
#![allow(non_snake_case)]
use dioxus::prelude::*;
use std::str::FromStr;
/// An error that occurs when parsing a route
#[derive(Debug, PartialEq)]
pub struct RouteParseError<E: std::fmt::Display> {
/// The attempted routes that failed to match
pub attempted_routes: Vec<E>,
}
impl<E: std::fmt::Display> std::fmt::Display for RouteParseError<E> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Route did not match:\nAttempted Matches:\n")?;
for (i, route) in self.attempted_routes.iter().enumerate() {
writeln!(f, "{}) {route}", i + 1)?;
}
Ok(())
}
}
/// Something that can be created from a query string
pub trait FromQuery {
/// Create an instance of `Self` from a query string
fn from_query(query: &str) -> Self;
}
impl<T: for<'a> From<&'a str>> FromQuery for T {
fn from_query(query: &str) -> Self {
T::from(query)
}
}
/// Something that can be created from a route segment
pub trait FromRouteSegment: Sized {
/// The error that can occur when parsing a route segment
type Err;
/// Create an instance of `Self` from a route segment
fn from_route_segment(route: &str) -> Result<Self, Self::Err>;
}
impl<T: FromStr> FromRouteSegment for T
where
<T as FromStr>::Err: std::fmt::Display,
{
type Err = <T as FromStr>::Err;
fn from_route_segment(route: &str) -> Result<Self, Self::Err> {
T::from_str(route)
}
}
/// Something that can be converted to route segments
pub trait ToRouteSegments {
/// Display the route segments
fn display_route_segements(self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result;
}
impl<I, T: std::fmt::Display> ToRouteSegments for I
where
I: IntoIterator<Item = T>,
{
fn display_route_segements(self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for segment in self {
write!(f, "/")?;
write!(f, "{}", segment)?;
}
Ok(())
}
}
/// Something that can be created from route segments
pub trait FromRouteSegments: Sized {
/// The error that can occur when parsing route segments
type Err;
/// Create an instance of `Self` from route segments
fn from_route_segments(segments: &[&str]) -> Result<Self, Self::Err>;
}
impl<I: std::iter::FromIterator<String>> FromRouteSegments for I {
type Err = <String as FromRouteSegment>::Err;
fn from_route_segments(segments: &[&str]) -> Result<Self, Self::Err> {
segments
.iter()
.map(|s| String::from_route_segment(s))
.collect()
}
}
/// Something that can be routed to
pub trait Routable: std::fmt::Display + std::str::FromStr + 'static {
/// Render the route at the given level
fn render<'a>(&self, cx: &'a ScopeState, level: usize) -> Element<'a>;
}
trait RoutableFactory {
type Err: std::fmt::Display;
type Routable: Routable + FromStr<Err = Self::Err>;
}
impl<R: Routable + FromStr> RoutableFactory for R
where
<R as FromStr>::Err: std::fmt::Display,
{
type Err = <R as FromStr>::Err;
type Routable = R;
}
trait RouteRenderable: std::fmt::Display + 'static {
fn render<'a>(&self, cx: &'a ScopeState, level: usize) -> Element<'a>;
}
impl<R: Routable> RouteRenderable for R
where
<R as FromStr>::Err: std::fmt::Display,
{
fn render<'a>(&self, cx: &'a ScopeState, level: usize) -> Element<'a> {
self.render(cx, level)
}
}