Updates for recent versions of Rust.

* Added lots of dyns
* Removed unused whitespace.
* Removed rust-toolchain because stable rust compiles the project.
* Fixed Doc-tests with ignore keyword.
This commit is contained in:
Sebastian Imlay 2019-10-04 14:52:33 -07:00
parent f15cf258af
commit 5695ec9b94
23 changed files with 170 additions and 171 deletions

View file

@ -4,4 +4,4 @@
/// A generic Error type that we use. It currently just aliases to `Box<std::error::Error>`,
/// but could change in the future.
pub type Error = Box<std::error::Error>;
pub type Error = Box<dyn std::error::Error>;

View file

@ -21,7 +21,7 @@ impl GenericRootView {
}
impl Props for GenericRootView {
fn set_props(&mut self, _: &mut Any) {}
fn set_props(&mut self, _: &mut dyn Any) {}
}
impl Component for GenericRootView {

View file

@ -1,6 +1,6 @@
//! Implements tree diffing, updating, and so on. Unlike a lot of the VDom implementations
//! you find littered around the web, this is a bit more ECS-ish, and expects Components to retain
//! their `ComponentKey` passed in their constructor if they want to update. Doing this
//! Implements tree diffing, updating, and so on. Unlike a lot of the VDom implementations
//! you find littered around the web, this is a bit more ECS-ish, and expects Components to retain
//! their `ComponentKey` passed in their constructor if they want to update. Doing this
//! enables us to avoid re-scanning or diffing an entire tree.
use std::sync::Mutex;
@ -48,12 +48,12 @@ impl RenderEngine {
// pub fn queue_update_for(&self, component_ptr: usize, updater: Box<Fn() -> Component + Send + Sync + 'static>) {
// }
/// `Window`'s (or anything "root" in nature) need to register with the
/// `Window`'s (or anything "root" in nature) need to register with the
/// reconciler for things like setState to work properly. When they do so,
/// they get a key back. When they want to instruct the global `RenderEngine`
/// to re-render or update their tree, they pass that key and whatever the new tree
/// they get a key back. When they want to instruct the global `RenderEngine`
/// to re-render or update their tree, they pass that key and whatever the new tree
/// should be.
pub fn register_root_component<C: Component + 'static>(&self, component: C) -> Result<ComponentKey, Box<Error>> {
pub fn register_root_component<C: Component + 'static>(&self, component: C) -> Result<ComponentKey, Box<dyn Error>> {
// Conceivably, this doesn't NEED to be a thing... but for now it is. If you've stumbled
// upon here, wayward traveler, in need of a non-native-root-component, please open an
// issue to discuss. :)
@ -75,7 +75,7 @@ impl RenderEngine {
Ok(component_key)
}
/// Rendering the root node is a bit different than rendering or updating other nodes, as we
/// Rendering the root node is a bit different than rendering or updating other nodes, as we
/// never want to unmount it, and the results come from a non-`Component` entity (e.g, a
/// `Window`). Thus, for this one, we do some manual mucking with what we know is the
/// root view (a `Window` or such root component would call this with it's registered
@ -85,7 +85,7 @@ impl RenderEngine {
key: ComponentKey,
dimensions: (f64, f64),
child: RSX
) -> Result<(), Box<Error>> {
) -> Result<(), Box<dyn Error>> {
let mut component_store = self.components.lock().unwrap();
let mut layout_store = self.layouts.lock().unwrap();
@ -122,7 +122,7 @@ impl RenderEngine {
width: Number::Defined(dimensions.0 as f32),
height: Number::Defined(dimensions.1 as f32)
})?;
walk_and_apply_styles(key, &mut component_store, &mut layout_store)?;
Ok(())
@ -138,8 +138,8 @@ fn recursively_diff_tree(
new_tree: RSX,
component_store: &mut ComponentStore,
layout_store: &mut LayoutStore
) -> Result<(), Box<Error>> {
// First we need to determine if this node is being replaced or updated. A replace happens if
) -> Result<(), Box<dyn Error>> {
// First we need to determine if this node is being replaced or updated. A replace happens if
// two nodes are different types - in this case, we check their tag values. This is also a case
// where, for instance, if the RSX tag is `::None` or `::VirtualText`, we'll treat it as
// replacing with nothing.
@ -173,7 +173,7 @@ fn recursively_diff_tree(
if let RSX::VirtualNode(mut child) = new_tree {
for new_child_tree in child.children {
match old_children.pop() {
// If there's a key in the old children for this position, it's
// If there's a key in the old children for this position, it's
// something we need to update, so let's recurse right back into it.
Some(old_child_key) => {
recursively_diff_tree(
@ -184,7 +184,7 @@ fn recursively_diff_tree(
)?;
},
// If there's no matching old key in this position, then we've got a
// If there's no matching old key in this position, then we've got a
// new component instance to mount. This part now diverts into the Mount
// phase.
None => {
@ -218,17 +218,17 @@ fn recursively_diff_tree(
/// tree, emitting required lifecycle events and persisting values. This happens in an inward-out
/// fashion, which helps avoid unnecessary reflow in environments where it can get tricky.
///
/// This method returns a Result, the `Ok` variant containing a tuple of Vecs. These are the child
/// This method returns a Result, the `Ok` variant containing a tuple of Vecs. These are the child
/// Component instances and Layout instances that need to be set in the stores.
fn mount_component_tree(
tree: VirtualNode,
component_store: &mut ComponentStore,
layout_store: &mut LayoutStore
) -> Result<ComponentKey, Box<Error>> {
) -> Result<ComponentKey, Box<dyn Error>> {
let key = component_store.new_key();
let component = (tree.create_component_fn)(key);
let is_native_backed = component.has_native_backing_node();
// let state = get_derived_state_from_props()
let mut instance = Instance {
tag: tree.tag,
@ -243,7 +243,7 @@ fn mount_component_tree(
THEME_ENGINE.configure_styles_for_keys(&instance.style_keys, &mut style, &mut instance.appearance);
instance.layout = Some(layout_store.new_node(style, vec![])?);
}
let rendered = instance.component.render(tree.children);
// instance.get_snapshot_before_update()
component_store.insert(key, instance)?;
@ -258,7 +258,7 @@ fn mount_component_tree(
for child_tree in child.children {
if let RSX::VirtualNode(child_tree) = child_tree {
let child_key = mount_component_tree(child_tree, component_store, layout_store)?;
component_store.add_child(key, child_key)?;
if is_native_backed {
link_layout_nodess(key, child_key, component_store, layout_store)?;
@ -267,7 +267,7 @@ fn mount_component_tree(
}
} else {
let child_key = mount_component_tree(child, component_store, layout_store)?;
component_store.add_child(key, child_key)?;
if is_native_backed {
link_layout_nodess(key, child_key, component_store, layout_store)?;
@ -298,12 +298,12 @@ fn unmount_component_tree(
key: ComponentKey,
component_store: &mut ComponentStore,
layout_store: &mut LayoutStore
) -> Result<Vec<LayoutNode>, Box<Error>> {
) -> Result<Vec<LayoutNode>, Box<dyn Error>> {
let mut instance = component_store.remove(key)?;
instance.component.component_will_unmount();
let mut layout_nodes = vec![];
let children = component_store.children(key)?;
for child in children {
match unmount_component_tree(child, component_store, layout_store) {
@ -327,8 +327,8 @@ fn unmount_component_tree(
}
/// Given a tree, will walk the branches until it finds the next root nodes to connect.
/// While this sounds slow, in practice it rarely has to go far in any direction. This could
/// potentially be done away with some hoisting magic in the `mount()` recursion, but I couldn't
/// While this sounds slow, in practice it rarely has to go far in any direction. This could
/// potentially be done away with some hoisting magic in the `mount()` recursion, but I couldn't
/// find a pattern that didn't feel like some utter magic in Rust.
///
/// It might be because I'm writing this at 3AM. Feel free to improve it.
@ -337,7 +337,7 @@ fn link_layout_nodess(
child: ComponentKey,
components: &mut ComponentStore,
layouts: &mut LayoutStore
) -> Result<(), Box<Error>> {
) -> Result<(), Box<dyn Error>> {
if let (Ok(parent_instance), Ok(child_instance)) = (components.get(parent), components.get(child)) {
if let (Some(parent_layout), Some(child_layout)) = (parent_instance.layout, child_instance.layout) {
layouts.add_child(parent_layout, child_layout)?;
@ -364,7 +364,7 @@ fn walk_and_apply_styles(
key: ComponentKey,
components: &mut ComponentStore,
layouts: &mut LayoutStore
) -> Result<(), Box<Error>> {
) -> Result<(), Box<dyn Error>> {
let instance = components.get_mut(key)?;
if let Some(layout_key) = instance.layout {

View file

@ -31,7 +31,7 @@ impl RSX {
pub fn node<P: Any + 'static>(
tag: &'static str,
styles: StylesList,
create_fn: fn(key: ComponentKey) -> Box<Component>,
create_fn: fn(key: ComponentKey) -> Box<dyn Component>,
props: P,
children: Vec<RSX>
) -> RSX {
@ -43,9 +43,9 @@ impl RSX {
children: children
})
}
/// Shorthand method for creating a new `RSX::VirtualText` instance. Rarely should you call
/// this yourself; the `rsx! {}` and `text!()` macros handle this for you.
/// this yourself; the `rsx! {}` and `text!()` macros handle this for you.
pub fn text(s: String) -> RSX {
RSX::VirtualText(VirtualText(s))
}

View file

@ -22,12 +22,12 @@ pub struct VirtualNode {
/// `Component` instances are created on-demand, if the reconciler deems it be so. This
/// is a closure that should return an instance of the correct type.
pub create_component_fn: fn(key: ComponentKey) -> Box<Component>,
pub create_component_fn: fn(key: ComponentKey) -> Box<dyn Component>,
/// When some RSX is returned, we scoop up the props inside a special block, and then shove
/// them in here as an `Any` object. When you `derive(Props)` on a `Component` struct, it
/// them in here as an `Any` object. When you `derive(Props)` on a `Component` struct, it
/// creates a setter that specifically handles downcasting and persisting props for you.
pub props: Box<Any>,
pub props: Box<dyn Any>,
/// Child components for this node.
pub children: Vec<RSX>

View file

@ -45,7 +45,7 @@ pub trait AppDelegate: Send + Sync {
fn will_resign_active(&mut self) {}
/// Fired when an Application has resigned active.
fn did_resign_active(&mut self) {}
fn did_resign_active(&mut self) {}
/// Fired when an Application is going to terminate. You can use this to, say, instruct the
/// system to "wait a minute, lemme finish".
@ -73,11 +73,11 @@ pub trait WindowDelegate: Send + Sync {
}
pub trait Props {
fn set_props(&mut self, new_props: &mut Any);
fn set_props(&mut self, new_props: &mut dyn Any);
}
/// The `Component` lifecycle, mostly inspired from React, with a few extra methods for views that
/// need to have a backing native layer. A good breakdown of the React Component lifecycle can be
/// need to have a backing native layer. A good breakdown of the React Component lifecycle can be
/// found [in this tweet](https://twitter.com/dan_abramov/status/981712092611989509?lang=en).
///
/// Alchemy does not currently implement Hooks, and at the moment has no plans to do so (the API
@ -106,7 +106,7 @@ pub trait Component: Props + Send + Sync {
/// `node`, you need to instruct the system how to remove it from the tree at your point.
fn remove_child_node(&self, _component: PlatformSpecificNodeType) {}
/// Given a configured 'appearance' and computed `layout`, this method should transform them
/// Given a configured 'appearance' and computed `layout`, this method should transform them
/// into appropriate calls to the backing native node.
fn apply_styles(&self, _appearance: &Appearance, _layout: &Layout) {}
@ -114,80 +114,80 @@ pub trait Component: Props + Send + Sync {
/// It should return an object to update the state, or null to update nothing.
/// This method exists for rare use cases where the state depends on changes in props over time.
fn get_derived_state_from_props(&self) {}
/// Invoked right before the most recently rendered output is committed to the backing layer tree.
/// It enables your component to capture some information from the tree (e.g. scroll position) before it's
/// potentially changed. Any value returned by this lifecycle will be passed as a parameter
/// It enables your component to capture some information from the tree (e.g. scroll position) before it's
/// potentially changed. Any value returned by this lifecycle will be passed as a parameter
/// to component_did_update().
///
/// This use case is not common, but it may occur in UIs like a chat thread that need to handle scroll
///
/// This use case is not common, but it may occur in UIs like a chat thread that need to handle scroll
/// position in a special way. A snapshot value (or None) should be returned.
fn get_snapshot_before_update(&self) {}
/// Invoked immediately after a component is mounted (inserted into the tree).
/// If you need to load data from a remote endpoint, this is a good place to instantiate the network request.
/// This method is also a good place to set up any subscriptions. If you do that, dont forget to unsubscribe
/// This method is also a good place to set up any subscriptions. If you do that, dont forget to unsubscribe
/// in component_will_unmount().
fn component_did_mount(&mut self) {}
/// Invoked immediately after updating occurs. This method is not called for the initial render.
/// This is also a good place to do network requests as long as you compare the current props to previous props
/// This is also a good place to do network requests as long as you compare the current props to previous props
/// (e.g. a network request may not be necessary if the props have not changed).
fn component_did_update(&mut self) {}
/// Invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this
/// method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that
/// Invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this
/// method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that
/// were created in component_did_mount().
///
/// You should not call set state in this method because the component will never be re-rendered. Once a
///
/// You should not call set state in this method because the component will never be re-rendered. Once a
/// component instance is unmounted, it will never be mounted again.
fn component_will_unmount(&mut self) {}
/// Invoked after an error has been thrown by a descendant component. Called during the "commit" phase,
/// Invoked after an error has been thrown by a descendant component. Called during the "commit" phase,
/// so side-effects are permitted. It should be used for things like logging errors (e.g,
/// Sentry).
fn component_did_catch(&mut self /* error: */) {}
/// Use this to let Alchemy know if a components output is not affected by the current change in state
/// or props. The default behavior is to re-render on every state change, and in the vast majority of
/// Use this to let Alchemy know if a components output is not affected by the current change in state
/// or props. The default behavior is to re-render on every state change, and in the vast majority of
/// cases you should rely on the default behavior.
///
/// This is invoked before rendering when new props or state are being received. Defaults to true. This
/// method is not called for the initial render or when force_update() is used. This method only exists
/// This is invoked before rendering when new props or state are being received. Defaults to true. This
/// method is not called for the initial render or when force_update() is used. This method only exists
/// as a performance optimization. Do not rely on it to “prevent” a rendering, as this can lead to bugs.
fn should_component_update(&self) -> bool { true }
/// The only required method for a `Component`. Should return a Result of RSX nodes, or an
/// Error (in very rare cases, such as trying to get a key from a strange HashMap or
/// something).
/// something).
///
/// The render() function should be pure, meaning that it does not modify component state, it
/// returns the same result each time its invoked, and it does not directly interact with the
/// The render() function should be pure, meaning that it does not modify component state, it
/// returns the same result each time its invoked, and it does not directly interact with the
/// backing rendering framework.
///
/// If you need to interact with the native layer, perform your work in component_did_mount() or the other
/// If you need to interact with the native layer, perform your work in component_did_mount() or the other
/// lifecycle methods instead. Keeping `render()` pure makes components easier to think about.
///
/// This method is not called if should_component_update() returns `false`.
fn render(&self, children: Vec<RSX>) -> Result<RSX, Error> { Ok(RSX::None) }
/// This lifecycle is invoked after an error has been thrown by a descendant component. It receives
/// This lifecycle is invoked after an error has been thrown by a descendant component. It receives
/// the error that was thrown as a parameter and should return a value to update state.
///
/// This is called during the "render" phase, so side-effects are not permitted.
/// This is called during the "render" phase, so side-effects are not permitted.
/// For those use cases, use component_did_catch() instead.
fn get_derived_state_from_error(&self, _error: ()) {}
/// By default, when your components state or props change, your component will re-render.
/// If your `render()` method depends on some other data, you can tell Alchemy that the component
/// By default, when your components state or props change, your component will re-render.
/// If your `render()` method depends on some other data, you can tell Alchemy that the component
/// needs re-rendering by calling `force_update()`.
///
/// Calling `force_update()` will cause `render()` to be called on the component, skipping
/// `should_component_update()`. This will trigger the normal lifecycle methods for child components,
/// including the `should_component_update()` method of each child. Alchemy will still only update the
/// Calling `force_update()` will cause `render()` to be called on the component, skipping
/// `should_component_update()`. This will trigger the normal lifecycle methods for child components,
/// including the `should_component_update()` method of each child. Alchemy will still only update the
/// backing widget tree if the markup changes.
///
/// Normally, you should try to avoid all uses of `force_update()` and only read from `this.props`
/// Normally, you should try to avoid all uses of `force_update()` and only read from `this.props`
/// and `this.state` in `render()`.
fn force_update(&self) {}
}