Skip to content
This repository was archived by the owner on Jul 19, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ yew-router-route-parser = {path = "crates/yew_router_route_parser", version = "0
yew-router-macro = {path = "crates/yew_router_macro", version = "0.8.0"}
nom = "5.0.1"
uuid = "0.8.1"
serde_json = "1.0.44"



Expand Down
5 changes: 4 additions & 1 deletion examples/servers/warp/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use std::path::PathBuf;

#[rustfmt::skip]
use warp::{
filters::BoxedFilter,
fs::File,
path::{self, Peek},
path::Peek,
path,
Filter, Reply,
};

Expand Down
15 changes: 6 additions & 9 deletions src/agent/bridge.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
//! Bridge to RouteAgent.
use crate::{
agent::{AgentState, RouteAgent},
route::Route,
};
use crate::{agent::{RouteAgent}, route::Route, RouteState};
use std::{
fmt::{Debug, Error as FmtError, Formatter},
ops::{Deref, DerefMut},
Expand All @@ -17,11 +14,11 @@ use yew::{
/// A component that owns this can send and receive messages from the agent.
pub struct RouteAgentBridge<T = ()>(Box<dyn Bridge<RouteAgent<T>>>)
where
for<'de> T: AgentState<'de>;
T: RouteState;

impl<T> RouteAgentBridge<T>
where
for<'de> T: AgentState<'de>,
T: RouteState,
{
/// Creates a new bridge.
pub fn new(callback: Callback<Route<T>>) -> Self {
Expand All @@ -39,20 +36,20 @@ where
}
}

impl<T: for<'de> AgentState<'de>> Debug for RouteAgentBridge<T> {
impl<T: RouteState> Debug for RouteAgentBridge<T> {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
f.debug_tuple("RouteAgentBridge").finish()
}
}

impl<T: for<'de> AgentState<'de>> Deref for RouteAgentBridge<T> {
impl<T: RouteState> Deref for RouteAgentBridge<T> {
type Target = Box<dyn Bridge<RouteAgent<T>>>;

fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: for<'de> AgentState<'de>> DerefMut for RouteAgentBridge<T> {
impl<T: RouteState> DerefMut for RouteAgentBridge<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
Expand Down
15 changes: 8 additions & 7 deletions src/agent/dispatcher.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
//! Dispatcher to RouteAgent.
use crate::agent::{AgentState, RouteAgent};
use crate::agent::{RouteAgent};
use std::{
fmt::{Debug, Error as FmtError, Formatter},
ops::{Deref, DerefMut},
};
use yew::agent::{Dispatched, Dispatcher};
use crate::RouteState;

/// A wrapped dispatcher to the route agent.
///
/// A component that owns and instance of this can send messages to the RouteAgent, but not receive them.
pub struct RouteAgentDispatcher<T = ()>(Dispatcher<RouteAgent<T>>)
where
for<'de> T: AgentState<'de>;
T: RouteState;

impl<T> RouteAgentDispatcher<T>
where
for<'de> T: AgentState<'de>,
T: RouteState
{
/// Creates a new bridge.
pub fn new() -> Self {
Expand All @@ -26,27 +27,27 @@ where

impl<T> Default for RouteAgentDispatcher<T>
where
for<'de> T: AgentState<'de>,
T: RouteState
{
fn default() -> Self {
Self::new()
}
}

impl<T: for<'de> AgentState<'de>> Debug for RouteAgentDispatcher<T> {
impl<T: RouteState> Debug for RouteAgentDispatcher<T> {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
f.debug_tuple("RouteAgentDispatcher").finish()
}
}

impl<T: for<'de> AgentState<'de>> Deref for RouteAgentDispatcher<T> {
impl<T: RouteState> Deref for RouteAgentDispatcher<T> {
type Target = Dispatcher<RouteAgent<T>>;

fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: for<'de> AgentState<'de>> DerefMut for RouteAgentDispatcher<T> {
impl<T: RouteState> DerefMut for RouteAgentDispatcher<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
Expand Down
10 changes: 4 additions & 6 deletions src/agent/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ pub use bridge::RouteAgentBridge;
mod dispatcher;
pub use dispatcher::RouteAgentDispatcher;

/// Any state that can be used in the router agent must meet the criteria of this trait.
pub trait AgentState<'de>: RouteState + Serialize + Deserialize<'de> + Debug {}
impl<'de, T> AgentState<'de> for T where T: RouteState + Serialize + Deserialize<'de> + Debug {}


/// Internal Message used for the RouteAgent.
#[derive(Debug)]
Expand Down Expand Up @@ -61,7 +59,7 @@ pub enum RouteRequest<T = ()> {
/// each other and associated components may not work as intended.
pub struct RouteAgent<T = ()>
where
for<'de> T: AgentState<'de>,
T: RouteState,
{
// In order to have the AgentLink<Self> below, apparently T must be constrained like this.
// Unfortunately, this means that everything related to an agent requires this constraint.
Expand All @@ -74,7 +72,7 @@ where
subscribers: HashSet<HandlerId>,
}

impl<T: for<'de> AgentState<'de>> Debug for RouteAgent<T> {
impl<T: RouteState> Debug for RouteAgent<T> {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
f.debug_struct("RouteAgent")
.field("link", &"-")
Expand All @@ -86,7 +84,7 @@ impl<T: for<'de> AgentState<'de>> Debug for RouteAgent<T> {

impl<T> Agent for RouteAgent<T>
where
for<'de> T: AgentState<'de>,
T: RouteState,
{
type Input = RouteRequest<T>;
type Message = Msg<T>;
Expand Down
2 changes: 1 addition & 1 deletion src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::RouterState;
// TODO This should also be PartialEq and Clone. Its blocked on Children not supporting that.
/// Properties for `RouterButton` and `RouterLink`.
#[derive(Properties, Default, Debug)]
pub struct Props<T: for<'de> RouterState<'de>> {
pub struct Props<T: RouterState> {
/// The route that will be set when the component is clicked.
pub link: String,
/// The state to set when changing the route.
Expand Down
4 changes: 2 additions & 2 deletions src/components/router_button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ use yew::virtual_dom::VNode;

/// Changes the route when clicked.
#[derive(Debug)]
pub struct RouterButton<T: for<'de> RouterState<'de> = ()> {
pub struct RouterButton<T: RouterState = ()> {
link: ComponentLink<Self>,
router: RouteAgentDispatcher<T>,
props: Props<T>,
}

impl<T: for<'de> RouterState<'de>> Component for RouterButton<T> {
impl<T: RouterState> Component for RouterButton<T> {
type Message = Msg;
type Properties = Props<T>;

Expand Down
4 changes: 2 additions & 2 deletions src/components/router_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ pub type RouterLink<T> = RouterAnchor<T>;

/// An anchor tag Component that when clicked, will navigate to the provided route.
#[derive(Debug)]
pub struct RouterAnchor<T: for<'de> RouterState<'de> = ()> {
pub struct RouterAnchor<T: RouterState = ()> {
link: ComponentLink<Self>,
router: RouteAgentDispatcher<T>,
props: Props<T>,
}

impl<T: for<'de> RouterState<'de>> Component for RouterAnchor<T> {
impl<T: RouterState> Component for RouterAnchor<T> {
type Message = Msg;
type Properties = Props<T>;

Expand Down
4 changes: 0 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ pub mod prelude {
pub use crate::switch::Switch;
pub use yew_router_macro::Switch;
// State restrictions
#[cfg(feature = "agent")]
pub use crate::agent::AgentState;
pub use crate::route::RouteState;
#[cfg(feature = "router")]
pub use crate::router::RouterState;
Expand All @@ -113,8 +111,6 @@ pub mod matcher;

pub use matcher::Captures;

#[cfg(feature = "agent")]
pub use crate::agent::AgentState;
pub use crate::route::RouteState;
#[cfg(feature = "router")]
pub use crate::router::RouterState;
Expand Down
12 changes: 7 additions & 5 deletions src/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
use crate::service::RouteService;
use serde::{Deserialize, Serialize};
use std::{fmt, ops::Deref};
use stdweb::{unstable::TryFrom, JsSerialize, Value};
use stdweb::{unstable::TryFrom, Value};
use std::fmt::Debug;
use serde::de::DeserializeOwned;

/// Any state that can be stored by the History API must meet the criteria of this trait.
pub trait RouteState: Clone + Default + JsSerialize + TryFrom<Value> + 'static {}
impl<T> RouteState for T where T: Clone + Default + JsSerialize + TryFrom<Value> + 'static {}
/// Any state that can be used in the router agent must meet the criteria of this trait.
pub trait RouteState: Serialize + DeserializeOwned + Debug + Clone + Default + TryFrom<Value> + 'static {}
impl<T> RouteState for T where T: Serialize + DeserializeOwned + Debug + Clone + Default + TryFrom<Value> + 'static {}

/// The representation of a route, segmented into different sections for easy access.
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
Expand Down Expand Up @@ -48,7 +50,7 @@ impl<T> Route<T> {

impl<T> fmt::Display for Route<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.route.fmt(f)
std::fmt::Display::fmt(&self.route, f)
}
}

Expand Down
33 changes: 14 additions & 19 deletions src/router.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
//! Router Component.

use crate::{
agent::{RouteAgentBridge, RouteRequest},
route::Route,
Switch,
};
use crate::{agent::{RouteAgentBridge, RouteRequest}, route::Route, Switch, RouteState};
use std::{
fmt::{self, Debug, Error as FmtError, Formatter},
rc::Rc,
};
use yew::{html, virtual_dom::VNode, Component, ComponentLink, Html, Properties, ShouldRender};

use crate::agent::AgentState;

/// Any state that can be managed by the `Router` must meet the criteria of this trait.
pub trait RouterState<'de>: AgentState<'de> + PartialEq {}
impl<'de, T> RouterState<'de> for T where T: AgentState<'de> + PartialEq {}
pub trait RouterState: RouteState + PartialEq {}
impl<T> RouterState for T where T: RouteState + PartialEq {}

/// Rendering control flow component.
///
Expand Down Expand Up @@ -59,15 +54,15 @@ impl<'de, T> RouterState<'de> for T where T: AgentState<'de> + PartialEq {}
/// ```
// TODO, can M just be removed due to not having to explicitly deal with callbacks anymore? - Just get rid of M
#[derive(Debug)]
pub struct Router<SW: Switch + Clone + 'static, T: for<'de> RouterState<'de> = ()> {
pub struct Router<SW: Switch + Clone + 'static, T: RouterState = ()> {
switch: Option<SW>,
props: Props<T, SW>,
router_agent: RouteAgentBridge<T>,
}

impl<SW, T> Router<SW, T>
where
T: for<'de> RouterState<'de>,
T: RouterState,
SW: Switch + Clone + 'static,
{
// TODO render fn name is overloaded now with that of the trait: Renderable<_> this should be changed. Maybe: display, show, switch, inner...
Expand Down Expand Up @@ -114,16 +109,16 @@ pub trait RenderFn<CTX: Component, SW>: Fn(SW) -> Html {}
impl<T, CTX: Component, SW> RenderFn<CTX, SW> for T where T: Fn(SW) -> Html {}
/// Owned Render function.
#[derive(Clone)]
pub struct Render<SW: Switch + Clone + 'static, T: for<'de> RouterState<'de> = ()>(
pub struct Render<SW: Switch + Clone + 'static, T: RouterState = ()>(
pub(crate) Rc<dyn RenderFn<Router<SW, T>, SW>>,
);
impl<T: for<'de> RouterState<'de>, SW: Switch + Clone> Render<SW, T> {
impl<T: RouterState, SW: Switch + Clone> Render<SW, T> {
/// New render function
fn new<F: RenderFn<Router<SW, T>, SW> + 'static>(f: F) -> Self {
Render(Rc::new(f))
}
}
impl<T: for<'de> RouterState<'de>, SW: Switch + Clone> Debug for Render<SW, T> {
impl<T: RouterState, SW: Switch + Clone> Debug for Render<SW, T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("Render").finish()
}
Expand All @@ -135,23 +130,23 @@ pub trait RedirectFn<SW, STATE>: Fn(Route<STATE>) -> SW {}
impl<T, SW, STATE> RedirectFn<SW, STATE> for T where T: Fn(Route<STATE>) -> SW {}
/// Clonable Redirect function
#[derive(Clone)]
pub struct Redirect<SW: Switch + 'static, STATE: for<'de> RouterState<'de>>(
pub struct Redirect<SW: Switch + 'static, STATE: RouterState>(
pub(crate) Rc<dyn RedirectFn<SW, STATE>>,
);
impl<STATE: for<'de> RouterState<'de>, SW: Switch + 'static> Redirect<SW, STATE> {
impl<STATE: RouterState, SW: Switch + 'static> Redirect<SW, STATE> {
fn new<F: RedirectFn<SW, STATE> + 'static>(f: F) -> Self {
Redirect(Rc::new(f))
}
}
impl<STATE: for<'de> RouterState<'de>, SW: Switch> Debug for Redirect<SW, STATE> {
impl<STATE: RouterState, SW: Switch> Debug for Redirect<SW, STATE> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("Redirect").finish()
}
}

/// Properties for Router.
#[derive(Properties, Clone)]
pub struct Props<T: for<'de> RouterState<'de>, SW: Switch + Clone + 'static> {
pub struct Props<T: RouterState, SW: Switch + Clone + 'static> {
/// Render function that takes a Switch and produces Html
#[props(required)]
pub render: Render<SW, T>,
Expand All @@ -161,15 +156,15 @@ pub struct Props<T: for<'de> RouterState<'de>, SW: Switch + Clone + 'static> {
pub redirect: Option<Redirect<SW, T>>,
}

impl<T: for<'de> RouterState<'de>, SW: Switch + Clone> Debug for Props<T, SW> {
impl<T: RouterState, SW: Switch + Clone> Debug for Props<T, SW> {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
f.debug_struct("Props").finish()
}
}

impl<T, SW> Component for Router<SW, T>
where
T: for<'de> RouterState<'de>,
T: RouterState,
SW: Switch + Clone + 'static,
{
type Message = Msg<T>;
Expand Down
Loading