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
20 changes: 10 additions & 10 deletions src/agent/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,44 @@ use yew::{
/// A wrapped bridge to the route agent.
///
/// A component that owns this can send and receive messages from the agent.
pub struct RouteAgentBridge<T = ()>(Box<dyn Bridge<RouteAgent<T>>>)
pub struct RouteAgentBridge<STATE = ()>(Box<dyn Bridge<RouteAgent<STATE>>>)
where
T: RouteState;
STATE: RouteState;

impl<T> RouteAgentBridge<T>
impl<STATE> RouteAgentBridge<STATE>
where
T: RouteState,
STATE: RouteState,
{
/// Creates a new bridge.
pub fn new(callback: Callback<Route<T>>) -> Self {
pub fn new(callback: Callback<Route<STATE>>) -> Self {
let router_agent = RouteAgent::bridge(callback);
RouteAgentBridge(router_agent)
}

/// Experimental, may be removed
///
/// Directly spawn a new Router
pub fn spawn(callback: Callback<Route<T>>) -> Self {
pub fn spawn(callback: Callback<Route<STATE>>) -> Self {
use yew::agent::Discoverer;
let router_agent = Context::spawn_or_join(Some(callback));
RouteAgentBridge(router_agent)
}
}

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

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

fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: RouteState> DerefMut for RouteAgentBridge<T> {
impl<STATE: RouteState> DerefMut for RouteAgentBridge<STATE> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
Expand Down
18 changes: 9 additions & 9 deletions src/agent/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ 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>>)
pub struct RouteAgentDispatcher<STATE = ()>(Dispatcher<RouteAgent<STATE>>)
where
T: RouteState;
STATE: RouteState;

impl<T> RouteAgentDispatcher<T>
impl<STATE> RouteAgentDispatcher<STATE>
where
T: RouteState
STATE: RouteState
{
/// Creates a new bridge.
pub fn new() -> Self {
Expand All @@ -25,23 +25,23 @@ where
}
}

impl<T> Default for RouteAgentDispatcher<T>
impl<STATE> Default for RouteAgentDispatcher<STATE>
where
T: RouteState
STATE: RouteState
{
fn default() -> Self {
Self::new()
}
}

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

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

fn deref(&self) -> &Self::Target {
&self.0
Expand Down
26 changes: 13 additions & 13 deletions src/agent/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ pub use dispatcher::RouteAgentDispatcher;

/// Internal Message used for the RouteAgent.
#[derive(Debug)]
pub enum Msg<T> {
pub enum Msg<STATE> {
/// Message for when the route is changed.
BrowserNavigationRouteChanged(Route<T>), // TODO make this a route?
BrowserNavigationRouteChanged(Route<STATE>), // TODO make this a route?
}

/// Input message type for interacting with the `RouteAgent'.
Expand Down Expand Up @@ -57,22 +57,22 @@ pub enum RouteRequest<T = ()> {
///
/// If you use multiple agents with different types, then the Agents won't be able to communicate to
/// each other and associated components may not work as intended.
pub struct RouteAgent<T = ()>
pub struct RouteAgent<STATE = ()>
where
T: RouteState,
STATE: 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.
link: AgentLink<RouteAgent<T>>,
link: AgentLink<RouteAgent<STATE>>,
/// The service through which communication with the browser happens.
route_service: RouteService<T>,
route_service: RouteService<STATE>,
/// A list of all entities connected to the router.
/// When a route changes, either initiated by the browser or by the app,
/// the route change will be broadcast to all listening entities.
subscribers: HashSet<HandlerId>,
}

impl<T: RouteState> Debug for RouteAgent<T> {
impl<STATE: RouteState> Debug for RouteAgent<STATE> {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
f.debug_struct("RouteAgent")
.field("link", &"-")
Expand All @@ -82,16 +82,16 @@ impl<T: RouteState> Debug for RouteAgent<T> {
}
}

impl<T> Agent for RouteAgent<T>
impl<STATE> Agent for RouteAgent<STATE>
where
T: RouteState,
STATE: RouteState,
{
type Input = RouteRequest<T>;
type Message = Msg<T>;
type Output = Route<T>;
type Input = RouteRequest<STATE>;
type Message = Msg<STATE>;
type Output = Route<STATE>;
type Reach = Context;

fn create(link: AgentLink<RouteAgent<T>>) -> Self {
fn create(link: AgentLink<RouteAgent<STATE>>) -> Self {
let callback = link.callback(Msg::BrowserNavigationRouteChanged);
let mut route_service = RouteService::new();
route_service.register_callback(callback);
Expand Down
4 changes: 2 additions & 2 deletions src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ use crate::RouterState;
// TODO This should no longer take link & String, and instead take a route: T implementing Switch
/// Properties for `RouterButton` and `RouterLink`.
#[derive(Properties, Default, Debug)]
pub struct Props<T: RouterState> {
pub struct Props<STATE: RouterState> {
/// The route that will be set when the component is clicked.
pub link: String,
/// The state to set when changing the route.
pub state: T,
pub state: STATE,
#[deprecated(note = "Use children field instead (nested html)")]
/// The text to display.
pub text: String,
Expand Down
10 changes: 5 additions & 5 deletions src/components/router_button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ use yew::virtual_dom::VNode;

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

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

fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
let router = RouteAgentDispatcher::new();
Expand Down
10 changes: 5 additions & 5 deletions src/components/router_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ 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: RouterState = ()> {
pub struct RouterAnchor<STATE: RouterState = ()> {
link: ComponentLink<Self>,
router: RouteAgentDispatcher<T>,
props: Props<T>,
router: RouteAgentDispatcher<STATE>,
props: Props<STATE>,
}

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

fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
let router = RouteAgentDispatcher::new();
Expand Down
14 changes: 7 additions & 7 deletions src/route.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ impl<T> RouteState for T where T: Serialize + DeserializeOwned + Debug + Clone +

/// The representation of a route, segmented into different sections for easy access.
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct Route<T = ()> {
pub struct Route<STATE = ()> {
/// The route string
pub route: String,
/// The state stored in the history api
pub state: T,
pub state: STATE,
}


Expand All @@ -36,23 +36,23 @@ impl Route<()> {
}
}

impl <T: Default> Route<T> {
impl <STATE: Default> Route<STATE> {
/// Creates a new route out of a string, setting the state to its default value.
pub fn new_default_state<U: AsRef<str>>(route: U) -> Self {
pub fn new_default_state<T: AsRef<str>>(route: T) -> Self {
Route {
route: route.as_ref().to_string(),
state: T::default(),
state: STATE::default(),
}
}
}

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

impl<T> Deref for Route<T> {
impl<STATE> Deref for Route<STATE> {
type Target = String;

fn deref(&self) -> &Self::Target {
Expand Down
46 changes: 23 additions & 23 deletions src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use yew::{html, virtual_dom::VNode, Component, ComponentLink, Html, Properties,

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

/// Rendering control flow component.
///
Expand Down Expand Up @@ -54,15 +54,15 @@ impl<T> RouterState for T where T: RouteState + 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: RouterState = ()> {
pub struct Router<SW: Switch + Clone + 'static, STATE: RouterState = ()> {
switch: Option<SW>,
props: Props<T, SW>,
router_agent: RouteAgentBridge<T>,
props: Props<STATE, SW>,
router_agent: RouteAgentBridge<STATE>,
}

impl<SW, T> Router<SW, T>
impl<SW, STATE> Router<SW, STATE>
where
T: RouterState,
STATE: 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 All @@ -87,38 +87,38 @@ where
/// });
/// # }
/// ```
pub fn render<F: RenderFn<Router<SW, T>, SW> + 'static>(f: F) -> Render<SW, T> {
pub fn render<F: RenderFn<Router<SW, STATE>, SW> + 'static>(f: F) -> Render<SW, STATE> {
Render::new(f)
}

/// Wrap a redirect function so that it can be used by the Router.
pub fn redirect<F: RedirectFn<SW, T> + 'static>(f: F) -> Option<Redirect<SW, T>> {
pub fn redirect<F: RedirectFn<SW, STATE> + 'static>(f: F) -> Option<Redirect<SW, STATE>> {
Some(Redirect::new(f))
}
}

/// Message for Router.
#[derive(Debug, Clone)]
pub enum Msg<T> {
pub enum Msg<STATE> {
/// Updates the route
UpdateRoute(Route<T>),
UpdateRoute(Route<STATE>),
}

/// Render function that takes a switched route and converts it to HTML
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: RouterState = ()>(
pub(crate) Rc<dyn RenderFn<Router<SW, T>, SW>>,
pub struct Render<SW: Switch + Clone + 'static, STATE: RouterState = ()>(
pub(crate) Rc<dyn RenderFn<Router<SW, STATE>, SW>>,
);
impl<T: RouterState, SW: Switch + Clone> Render<SW, T> {
impl<STATE: RouterState, SW: Switch + Clone> Render<SW, STATE> {
/// New render function
fn new<F: RenderFn<Router<SW, T>, SW> + 'static>(f: F) -> Self {
fn new<F: RenderFn<Router<SW, STATE>, SW> + 'static>(f: F) -> Self {
Render(Rc::new(f))
}
}
impl<T: RouterState, SW: Switch + Clone> Debug for Render<SW, T> {
impl<STATE: RouterState, SW: Switch + Clone> Debug for Render<SW, STATE> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("Render").finish()
}
Expand Down Expand Up @@ -146,29 +146,29 @@ impl<STATE: RouterState, SW: Switch> Debug for Redirect<SW, STATE> {

/// Properties for Router.
#[derive(Properties, Clone)]
pub struct Props<T: RouterState, SW: Switch + Clone + 'static> {
pub struct Props<STATE: RouterState, SW: Switch + Clone + 'static> {
/// Render function that takes a Switch and produces Html
#[props(required)]
pub render: Render<SW, T>,
pub render: Render<SW, STATE>,
/// Optional redirect function that will convert the route to a known switch variant if explicit matching fails.
/// This should mostly be used to handle 404s and redirection.
/// It is not strictly necessary as your Switch is capable of handling unknown routes using `#[to="/{*:any}"]`.
pub redirect: Option<Redirect<SW, T>>,
pub redirect: Option<Redirect<SW, STATE>>,
}

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

impl<T, SW> Component for Router<SW, T>
impl<STATE, SW> Component for Router<SW, STATE>
where
T: RouterState,
STATE: RouterState,
SW: Switch + Clone + 'static,
{
type Message = Msg<T>;
type Properties = Props<T, SW>;
type Message = Msg<STATE>;
type Properties = Props<STATE, SW>;

fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
let callback = link.callback(Msg::UpdateRoute);
Expand Down
Loading