From 74b11708068107406d447e918d77c36bd3ee284b Mon Sep 17 00:00:00 2001 From: Henry Zimmerman Date: Wed, 18 Dec 2019 06:43:44 -0500 Subject: [PATCH 1/2] rename the type parameter that indicates history state --- src/components/mod.rs | 4 ++-- src/components/router_button.rs | 10 +++++----- src/components/router_link.rs | 10 +++++----- src/route.rs | 14 +++++++------- src/router.rs | 8 ++++---- src/service.rs | 30 +++++++++++++++--------------- src/switch.rs | 22 +++++++++++----------- 7 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/components/mod.rs b/src/components/mod.rs index a3cdf41..77797d2 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -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 { +pub struct Props { /// 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, diff --git a/src/components/router_button.rs b/src/components/router_button.rs index c2b9bca..ba470ce 100644 --- a/src/components/router_button.rs +++ b/src/components/router_button.rs @@ -11,15 +11,15 @@ use yew::virtual_dom::VNode; /// Changes the route when clicked. #[derive(Debug)] -pub struct RouterButton { +pub struct RouterButton { link: ComponentLink, - router: RouteAgentDispatcher, - props: Props, + router: RouteAgentDispatcher, + props: Props, } -impl Component for RouterButton { +impl Component for RouterButton { type Message = Msg; - type Properties = Props; + type Properties = Props; fn create(props: Self::Properties, link: ComponentLink) -> Self { let router = RouteAgentDispatcher::new(); diff --git a/src/components/router_link.rs b/src/components/router_link.rs index 9a04a33..1781e99 100644 --- a/src/components/router_link.rs +++ b/src/components/router_link.rs @@ -17,15 +17,15 @@ pub type RouterLink = RouterAnchor; /// An anchor tag Component that when clicked, will navigate to the provided route. #[derive(Debug)] -pub struct RouterAnchor { +pub struct RouterAnchor { link: ComponentLink, - router: RouteAgentDispatcher, - props: Props, + router: RouteAgentDispatcher, + props: Props, } -impl Component for RouterAnchor { +impl Component for RouterAnchor { type Message = Msg; - type Properties = Props; + type Properties = Props; fn create(props: Self::Properties, link: ComponentLink) -> Self { let router = RouteAgentDispatcher::new(); diff --git a/src/route.rs b/src/route.rs index b80affc..d6f955a 100644 --- a/src/route.rs +++ b/src/route.rs @@ -16,11 +16,11 @@ impl 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 { +pub struct Route { /// The route string pub route: String, /// The state stored in the history api - pub state: T, + pub state: STATE, } @@ -36,23 +36,23 @@ impl Route<()> { } } -impl Route { +impl Route { /// Creates a new route out of a string, setting the state to its default value. - pub fn new_default_state>(route: U) -> Self { + pub fn new_default_state>(route: T) -> Self { Route { route: route.as_ref().to_string(), - state: T::default(), + state: STATE::default(), } } } -impl fmt::Display for Route { +impl fmt::Display for Route { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { std::fmt::Display::fmt(&self.route, f) } } -impl Deref for Route { +impl Deref for Route { type Target = String; fn deref(&self) -> &Self::Target { diff --git a/src/router.rs b/src/router.rs index 66186a1..db68e1a 100644 --- a/src/router.rs +++ b/src/router.rs @@ -162,13 +162,13 @@ impl Debug for Props { } } -impl Component for Router +impl Component for Router where - T: RouterState, + STATE: RouterState, SW: Switch + Clone + 'static, { - type Message = Msg; - type Properties = Props; + type Message = Msg; + type Properties = Props; fn create(props: Self::Properties, link: ComponentLink) -> Self { let callback = link.callback(Msg::UpdateRoute); diff --git a/src/service.rs b/src/service.rs index f80ae9b..bc50109 100644 --- a/src/service.rs +++ b/src/service.rs @@ -14,19 +14,19 @@ use stdweb::js; /// /// The `T` determines what route state can be stored in the route service. #[derive(Debug)] -pub struct RouteService { +pub struct RouteService { history: History, location: Location, event_listener: Option, - phantom_data: PhantomData, + phantom_data: PhantomData, } -impl Default for RouteService +impl Default for RouteService where - T: RouteState, + STATE: RouteState, { fn default() -> Self { - RouteService::::new() + RouteService::::new() } } @@ -70,20 +70,20 @@ impl RouteService { } } -impl RouteService +impl RouteService where - T: RouteState, + STATE: RouteState, { /// Registers a callback to the route service. /// Callbacks will be called when the History API experiences a change such as /// popping a state off of its stack when the forward or back buttons are pressed. - pub fn register_callback(&mut self, callback: Callback>) { + pub fn register_callback(&mut self, callback: Callback>) { self.event_listener = Some(window().add_event_listener(move |event: PopStateEvent| { let state_value: Value = event.state(); let state_string: String = String::try_from(state_value).unwrap_or_default(); - let state: T = serde_json::from_str(&state_string).unwrap_or_else(|_| { + let state: STATE = serde_json::from_str(&state_string).unwrap_or_else(|_| { log::error!("Could not deserialize state string"); - T::default() + STATE::default() }); @@ -101,7 +101,7 @@ where /// and creates a history entry that can be navigated via the forward and back buttons. /// /// The route should be a relative path that starts with a `/`. - pub fn set_route(&mut self, route: &str, state: T) { + pub fn set_route(&mut self, route: &str, state: STATE) { let state_string: String = serde_json::to_string(&state).unwrap_or_else(|_| { log::error!("Could not serialize state string"); "".to_string() @@ -111,7 +111,7 @@ where /// Replaces the route with another one removing the most recent history event and /// creating another history event in its place. - pub fn replace_route(&mut self, route: &str, state: T) { + pub fn replace_route(&mut self, route: &str, state: STATE) { let state_string: String = serde_json::to_string(&state).unwrap_or_else(|_| { log::error!("Could not serialize state string"); "".to_string() @@ -120,14 +120,14 @@ where } /// Gets the concatenated path, query, and fragment. - pub fn get_route(&self) -> Route { + pub fn get_route(&self) -> Route { let route_string = Self::get_route_from_location(&self.location); - let state: T = get_state_string(&self.history) + let state: STATE = get_state_string(&self.history) .or_else(|| { log::trace!("History state is empty"); None }) - .and_then(|state_string| -> Option>{ + .and_then(|state_string| -> Option>{ serde_json::from_str(&state_string) .ok() .or_else(|| { diff --git a/src/switch.rs b/src/switch.rs index 736a649..ad3978e 100644 --- a/src/switch.rs +++ b/src/switch.rs @@ -49,15 +49,15 @@ pub type Routable = Switch; /// ``` pub trait Switch: Sized { /// Based on a route, possibly produce an itself. - fn switch(route: Route) -> Option { + fn switch(route: Route) -> Option { Self::from_route_part(route.route, Some(route.state)).0 } /// Get self from a part of the state - fn from_route_part(part: String, state: Option) -> (Option, Option); + fn from_route_part(part: String, state: Option) -> (Option, Option); /// Build part of a route from itself. - fn build_route_section(self, route: &mut String) -> Option; + fn build_route_section(self, route: &mut String) -> Option; /// Called when the key (the named capture group) can't be located. Instead of failing outright, /// a default item can be provided instead. @@ -81,7 +81,7 @@ pub trait Switch: Sized { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct LeadingSlash(pub T); impl Switch for LeadingSlash { - fn from_route_part(part: String, state: Option) -> (Option, Option) { + fn from_route_part(part: String, state: Option) -> (Option, Option) { if part.starts_with('/') { let part = part[1..].to_string(); let (inner, state) = U::from_route_part(part, state); @@ -103,7 +103,7 @@ pub struct Permissive(pub Option); impl Switch for Permissive { /// Option is very permissive in what is allowed. - fn from_route_part(part: String, state: Option) -> (Option, Option) { + fn from_route_part(part: String, state: Option) -> (Option, Option) { let (inner, inner_state) = U::from_route_part(part, state); if inner.is_some() { (Some(Permissive(inner)), inner_state) @@ -113,7 +113,7 @@ impl Switch for Permissive { } } - fn build_route_section(self, route: &mut String) -> Option { + fn build_route_section(self, route: &mut String) -> Option { if let Some(inner) = self.0 { inner.build_route_section(route) } else { @@ -134,7 +134,7 @@ impl Switch for Permissive { #[derive(Debug, PartialEq, Clone, Copy)] pub struct AllowMissing(pub Option); impl Switch for AllowMissing { - fn from_route_part(part: String, state: Option) -> (Option, Option) { + fn from_route_part(part: String, state: Option) -> (Option, Option) { let route = part.clone(); let (inner, inner_state) = U::from_route_part(part, state); @@ -152,7 +152,7 @@ impl Switch for AllowMissing { } } - fn build_route_section(self, route: &mut String) -> Option { + fn build_route_section(self, route: &mut String) -> Option { if let AllowMissing(Some(inner)) = self { inner.build_route_section(route) } else { @@ -162,19 +162,19 @@ impl Switch for AllowMissing { } /// Builds a route from a switch. -fn build_route_from_switch(switch: T) -> Route { +fn build_route_from_switch(switch: SW) -> Route { // URLs are recommended to not be over 255 characters, // although browsers frequently support up to about 2000. // Routes, being a subset of URLs should probably be smaller than 255 characters for the vast // majority of circumstances, preventing reallocation under most conditions. let mut buf = String::with_capacity(255); - let state = switch.build_route_section(&mut buf).unwrap_or_default(); + let state: STATE = switch.build_route_section(&mut buf).unwrap_or_default(); buf.shrink_to_fit(); Route { route: buf, state } } -impl From for Route { +impl From for Route { fn from(switch: SW) -> Self { build_route_from_switch(switch) } From ad294b773e27e106dc22fd0483016b4b97c60333 Mon Sep 17 00:00:00 2001 From: Henry Zimmerman Date: Wed, 18 Dec 2019 06:54:19 -0500 Subject: [PATCH 2/2] update agent --- src/agent/bridge.rs | 20 ++++++++++---------- src/agent/dispatcher.rs | 18 +++++++++--------- src/agent/mod.rs | 26 +++++++++++++------------- src/router.rs | 38 +++++++++++++++++++------------------- 4 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/agent/bridge.rs b/src/agent/bridge.rs index 3d05825..c31dbc0 100644 --- a/src/agent/bridge.rs +++ b/src/agent/bridge.rs @@ -12,16 +12,16 @@ 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(Box>>) +pub struct RouteAgentBridge(Box>>) where - T: RouteState; + STATE: RouteState; -impl RouteAgentBridge +impl RouteAgentBridge where - T: RouteState, + STATE: RouteState, { /// Creates a new bridge. - pub fn new(callback: Callback>) -> Self { + pub fn new(callback: Callback>) -> Self { let router_agent = RouteAgent::bridge(callback); RouteAgentBridge(router_agent) } @@ -29,27 +29,27 @@ where /// Experimental, may be removed /// /// Directly spawn a new Router - pub fn spawn(callback: Callback>) -> Self { + pub fn spawn(callback: Callback>) -> Self { use yew::agent::Discoverer; let router_agent = Context::spawn_or_join(Some(callback)); RouteAgentBridge(router_agent) } } -impl Debug for RouteAgentBridge { +impl Debug for RouteAgentBridge { fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { f.debug_tuple("RouteAgentBridge").finish() } } -impl Deref for RouteAgentBridge { - type Target = Box>>; +impl Deref for RouteAgentBridge { + type Target = Box>>; fn deref(&self) -> &Self::Target { &self.0 } } -impl DerefMut for RouteAgentBridge { +impl DerefMut for RouteAgentBridge { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } diff --git a/src/agent/dispatcher.rs b/src/agent/dispatcher.rs index b1fd0f9..5e35f97 100644 --- a/src/agent/dispatcher.rs +++ b/src/agent/dispatcher.rs @@ -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(Dispatcher>) +pub struct RouteAgentDispatcher(Dispatcher>) where - T: RouteState; + STATE: RouteState; -impl RouteAgentDispatcher +impl RouteAgentDispatcher where - T: RouteState + STATE: RouteState { /// Creates a new bridge. pub fn new() -> Self { @@ -25,23 +25,23 @@ where } } -impl Default for RouteAgentDispatcher +impl Default for RouteAgentDispatcher where - T: RouteState + STATE: RouteState { fn default() -> Self { Self::new() } } -impl Debug for RouteAgentDispatcher { +impl Debug for RouteAgentDispatcher { fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { f.debug_tuple("RouteAgentDispatcher").finish() } } -impl Deref for RouteAgentDispatcher { - type Target = Dispatcher>; +impl Deref for RouteAgentDispatcher { + type Target = Dispatcher>; fn deref(&self) -> &Self::Target { &self.0 diff --git a/src/agent/mod.rs b/src/agent/mod.rs index a132e5f..e92dcab 100644 --- a/src/agent/mod.rs +++ b/src/agent/mod.rs @@ -24,9 +24,9 @@ pub use dispatcher::RouteAgentDispatcher; /// Internal Message used for the RouteAgent. #[derive(Debug)] -pub enum Msg { +pub enum Msg { /// Message for when the route is changed. - BrowserNavigationRouteChanged(Route), // TODO make this a route? + BrowserNavigationRouteChanged(Route), // TODO make this a route? } /// Input message type for interacting with the `RouteAgent'. @@ -57,22 +57,22 @@ pub enum RouteRequest { /// /// 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 +pub struct RouteAgent where - T: RouteState, + STATE: RouteState, { // In order to have the AgentLink below, apparently T must be constrained like this. // Unfortunately, this means that everything related to an agent requires this constraint. - link: AgentLink>, + link: AgentLink>, /// The service through which communication with the browser happens. - route_service: RouteService, + route_service: RouteService, /// 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, } -impl Debug for RouteAgent { +impl Debug for RouteAgent { fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { f.debug_struct("RouteAgent") .field("link", &"-") @@ -82,16 +82,16 @@ impl Debug for RouteAgent { } } -impl Agent for RouteAgent +impl Agent for RouteAgent where - T: RouteState, + STATE: RouteState, { - type Input = RouteRequest; - type Message = Msg; - type Output = Route; + type Input = RouteRequest; + type Message = Msg; + type Output = Route; type Reach = Context; - fn create(link: AgentLink>) -> Self { + fn create(link: AgentLink>) -> Self { let callback = link.callback(Msg::BrowserNavigationRouteChanged); let mut route_service = RouteService::new(); route_service.register_callback(callback); diff --git a/src/router.rs b/src/router.rs index db68e1a..d111deb 100644 --- a/src/router.rs +++ b/src/router.rs @@ -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 RouterState for T where T: RouteState + PartialEq {} +impl RouterState for STATE where STATE: RouteState + PartialEq {} /// Rendering control flow component. /// @@ -54,15 +54,15 @@ impl 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 { +pub struct Router { switch: Option, - props: Props, - router_agent: RouteAgentBridge, + props: Props, + router_agent: RouteAgentBridge, } -impl Router +impl Router 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... @@ -87,21 +87,21 @@ where /// }); /// # } /// ``` - pub fn render, SW> + 'static>(f: F) -> Render { + pub fn render, SW> + 'static>(f: F) -> Render { Render::new(f) } /// Wrap a redirect function so that it can be used by the Router. - pub fn redirect + 'static>(f: F) -> Option> { + pub fn redirect + 'static>(f: F) -> Option> { Some(Redirect::new(f)) } } /// Message for Router. #[derive(Debug, Clone)] -pub enum Msg { +pub enum Msg { /// Updates the route - UpdateRoute(Route), + UpdateRoute(Route), } /// Render function that takes a switched route and converts it to HTML @@ -109,16 +109,16 @@ pub trait RenderFn: Fn(SW) -> Html {} impl RenderFn for T where T: Fn(SW) -> Html {} /// Owned Render function. #[derive(Clone)] -pub struct Render( - pub(crate) Rc, SW>>, +pub struct Render( + pub(crate) Rc, SW>>, ); -impl Render { +impl Render { /// New render function - fn new, SW> + 'static>(f: F) -> Self { + fn new, SW> + 'static>(f: F) -> Self { Render(Rc::new(f)) } } -impl Debug for Render { +impl Debug for Render { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("Render").finish() } @@ -146,17 +146,17 @@ impl Debug for Redirect { /// Properties for Router. #[derive(Properties, Clone)] -pub struct Props { +pub struct Props { /// Render function that takes a Switch and produces Html #[props(required)] - pub render: Render, + pub render: Render, /// 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>, + pub redirect: Option>, } -impl Debug for Props { +impl Debug for Props { fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> { f.debug_struct("Props").finish() }