chore: make clippy happy

This commit is contained in:
Jonathan Kelley committed 2022-11-29 16:46:25 -05:00
1 parent 7c3d308ab5
commit 03aea885cf
12 files changed
+67 -103

No files matched your search

+6 -2
View File
@@ -8,7 +8,11 @@ use crate::{
}; };
/// A trait that essentially allows VComponentProps to be used generically /// A trait that essentially allows VComponentProps to be used generically
pub unsafe trait AnyProps<'a> { ///
/// # Safety
///
/// This should not be implemented outside this module
pub(crate) unsafe trait AnyProps<'a> {
fn props_ptr(&self) -> *const (); fn props_ptr(&self) -> *const ();
fn render(&'a self, bump: &'a ScopeState) -> RenderReturn<'a>; fn render(&'a self, bump: &'a ScopeState) -> RenderReturn<'a>;
unsafe fn memoize(&self, other: &dyn AnyProps) -> bool; unsafe fn memoize(&self, other: &dyn AnyProps) -> bool;
@@ -64,6 +68,6 @@ where
}); });
// Call the render function directly // Call the render function directly
(self.render_fn)(scope).as_return(cx) (self.render_fn)(scope).into_return(cx)
} }
} }
+5 -17
View File
@@ -31,7 +31,7 @@ impl ElementRef {
} }
} }
impl<'b> VirtualDom { impl VirtualDom {
pub(crate) fn next_element(&mut self, template: &VNode, path: &'static [u8]) -> ElementId { pub(crate) fn next_element(&mut self, template: &VNode, path: &'static [u8]) -> ElementId {
let entry = self.elements.vacant_entry(); let entry = self.elements.vacant_entry();
let id = entry.key(); let id = entry.key();
@@ -68,9 +68,8 @@ impl<'b> VirtualDom {
if let Some(root) = scope.as_ref().try_root_node() { if let Some(root) = scope.as_ref().try_root_node() {
let root = unsafe { root.extend_lifetime_ref() }; let root = unsafe { root.extend_lifetime_ref() };
match root { if let RenderReturn::Sync(Ok(node)) = root {
RenderReturn::Sync(Ok(node)) => self.drop_scope_inner(node), self.drop_scope_inner(node)
_ => {}
} }
} }
@@ -78,9 +77,8 @@ impl<'b> VirtualDom {
if let Some(root) = unsafe { scope.as_ref().previous_frame().try_load_node() } { if let Some(root) = unsafe { scope.as_ref().previous_frame().try_load_node() } {
let root = unsafe { root.extend_lifetime_ref() }; let root = unsafe { root.extend_lifetime_ref() };
match root { if let RenderReturn::Sync(Ok(node)) = root {
RenderReturn::Sync(Ok(node)) => self.drop_scope_inner(node), self.drop_scope_inner(node)
_ => {}
} }
} }
@@ -123,16 +121,6 @@ impl ElementPath {
} }
} }
#[test]
fn path_ascendant() {
// assert!(&ElementPath::Deep(&[]).is_ascendant(&&[0_u8]));
// assert!(&ElementPath::Deep(&[1, 2]), &[1, 2, 3]);
// assert!(!is_path_ascendant(
// &ElementPath::Deep(&[1, 2, 3, 4]),
// &[1, 2, 3]
// ));
}
impl PartialEq<&[u8]> for ElementPath { impl PartialEq<&[u8]> for ElementPath {
fn eq(&self, other: &&[u8]) -> bool { fn eq(&self, other: &&[u8]) -> bool {
match *self { match *self {
+5 -9
View File
@@ -224,7 +224,7 @@ impl<'b> VirtualDom {
} }
for node in template.template.roots { for node in template.template.roots {
self.create_static_node(template, node); self.create_static_node(node);
} }
self.mutations.template_mutations.push(SaveTemplate { self.mutations.template_mutations.push(SaveTemplate {
@@ -233,11 +233,7 @@ impl<'b> VirtualDom {
}); });
} }
pub(crate) fn create_static_node( pub(crate) fn create_static_node(&mut self, node: &'b TemplateNode<'static>) {
&mut self,
template: &'b VNode<'b>,
node: &'b TemplateNode<'static>,
) {
match *node { match *node {
// Todo: create the children's template // Todo: create the children's template
TemplateNode::Dynamic(_) => self TemplateNode::Dynamic(_) => self
@@ -275,7 +271,7 @@ impl<'b> VirtualDom {
self.mutations self.mutations
.template_mutations .template_mutations
.extend(attrs.into_iter().filter_map(|attr| match attr { .extend(attrs.iter().filter_map(|attr| match attr {
TemplateAttribute::Static { TemplateAttribute::Static {
name, name,
value, value,
@@ -294,8 +290,8 @@ impl<'b> VirtualDom {
} }
children children
.into_iter() .iter()
.for_each(|child| self.create_static_node(template, child)); .for_each(|child| self.create_static_node(child));
self.mutations self.mutations
.template_mutations .template_mutations
+4 -4
View File
@@ -320,14 +320,14 @@ impl<'b> VirtualDom {
Text(t) => self.reclaim(t.id.get()), Text(t) => self.reclaim(t.id.get()),
Fragment(VFragment::Empty(t)) => self.reclaim(t.get()), Fragment(VFragment::Empty(t)) => self.reclaim(t.get()),
Fragment(VFragment::NonEmpty(nodes)) => { Fragment(VFragment::NonEmpty(nodes)) => {
nodes.into_iter().for_each(|node| self.clean_up_node(node)) nodes.iter().for_each(|node| self.clean_up_node(node))
} }
}; };
} }
// we clean up nodes with dynamic attributes, provided the node is unique and not a root node // we clean up nodes with dynamic attributes, provided the node is unique and not a root node
let mut id = None; let mut id = None;
for (idx, attr) in node.dynamic_attrs.into_iter().enumerate() { for (idx, attr) in node.dynamic_attrs.iter().enumerate() {
// We'll clean up the root nodes either way, so don't worry // We'll clean up the root nodes either way, so don't worry
if node.template.attr_paths[idx].len() == 1 { if node.template.attr_paths[idx].len() == 1 {
continue; continue;
@@ -620,7 +620,7 @@ impl<'b> VirtualDom {
// If none of the old keys are reused by the new children, then we remove all the remaining old children and // If none of the old keys are reused by the new children, then we remove all the remaining old children and
// create the new children afresh. // create the new children afresh.
if shared_keys.is_empty() { if shared_keys.is_empty() {
if let Some(_) = old.get(0) { if old.get(0).is_some() {
self.remove_nodes(&old[1..]); self.remove_nodes(&old[1..]);
self.replace_many(&old[0], new); self.replace_many(&old[0], new);
} else { } else {
@@ -744,7 +744,7 @@ impl<'b> VirtualDom {
/// Remove these nodes from the dom /// Remove these nodes from the dom
/// Wont generate mutations for the inner nodes /// Wont generate mutations for the inner nodes
fn remove_nodes(&mut self, nodes: &'b [VNode<'b>]) { fn remove_nodes(&mut self, nodes: &'b [VNode<'b>]) {
nodes.into_iter().for_each(|node| self.remove_node(node)); nodes.iter().for_each(|node| self.remove_node(node));
} }
fn remove_node(&mut self, node: &'b VNode<'b>) { fn remove_node(&mut self, node: &'b VNode<'b>) {
+18 -22
View File
@@ -106,10 +106,10 @@ impl ScopeState {
} }
pub trait ComponentReturn<'a, A = ()> { pub trait ComponentReturn<'a, A = ()> {
fn as_return(self, cx: &'a ScopeState) -> RenderReturn<'a>; fn into_return(self, cx: &'a ScopeState) -> RenderReturn<'a>;
} }
impl<'a> ComponentReturn<'a> for Element<'a> { impl<'a> ComponentReturn<'a> for Element<'a> {
fn as_return(self, _cx: &ScopeState) -> RenderReturn<'a> { fn into_return(self, _cx: &ScopeState) -> RenderReturn<'a> {
RenderReturn::Sync(self) RenderReturn::Sync(self)
} }
} }
@@ -119,11 +119,9 @@ impl<'a, F> ComponentReturn<'a, AsyncMarker> for F
where where
F: Future<Output = Element<'a>> + 'a, F: Future<Output = Element<'a>> + 'a,
{ {
fn as_return(self, cx: &'a ScopeState) -> RenderReturn<'a> { fn into_return(self, cx: &'a ScopeState) -> RenderReturn<'a> {
let f: &mut dyn Future<Output = Element<'a>> = cx.bump().alloc(self); let f: &mut dyn Future<Output = Element<'a>> = cx.bump().alloc(self);
let boxed = unsafe { BumpBox::from_raw(f) }; RenderReturn::Async(unsafe { BumpBox::from_raw(f) })
let pined: BumpBox<_> = boxed.into();
RenderReturn::Async(pined)
} }
} }
@@ -148,18 +146,18 @@ pub trait IntoDynNode<'a, A = ()> {
fn into_vnode(self, cx: &'a ScopeState) -> DynamicNode<'a>; fn into_vnode(self, cx: &'a ScopeState) -> DynamicNode<'a>;
} }
impl<'a, 'b> IntoDynNode<'a> for () { impl<'a> IntoDynNode<'a> for () {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> { fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
DynamicNode::Fragment(VFragment::Empty(Cell::new(ElementId(0)))) DynamicNode::Fragment(VFragment::Empty(Cell::new(ElementId(0))))
} }
} }
impl<'a, 'b> IntoDynNode<'a> for VNode<'a> { impl<'a> IntoDynNode<'a> for VNode<'a> {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> { fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
DynamicNode::Fragment(VFragment::NonEmpty(_cx.bump().alloc([self]))) DynamicNode::Fragment(VFragment::NonEmpty(_cx.bump().alloc([self])))
} }
} }
impl<'a, 'b, T: IntoDynNode<'a>> IntoDynNode<'a> for Option<T> { impl<'a, T: IntoDynNode<'a>> IntoDynNode<'a> for Option<T> {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> { fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
match self { match self {
Some(val) => val.into_vnode(_cx), Some(val) => val.into_vnode(_cx),
@@ -183,7 +181,7 @@ impl<'a, 'b> IntoDynNode<'a> for LazyNodes<'a, 'b> {
} }
} }
impl<'b> IntoDynNode<'_> for &'b str { impl<'a> IntoDynNode<'_> for &'a str {
fn into_vnode(self, cx: &ScopeState) -> DynamicNode { fn into_vnode(self, cx: &ScopeState) -> DynamicNode {
cx.text(format_args!("{}", self)) cx.text(format_args!("{}", self))
} }
@@ -201,25 +199,23 @@ impl<'b> IntoDynNode<'b> for Arguments<'_> {
} }
} }
impl<'a, 'b> IntoDynNode<'a> for &VNode<'a> { impl<'a> IntoDynNode<'a> for &'a VNode<'a> {
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> { fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
todo!() DynamicNode::Fragment(VFragment::NonEmpty(_cx.bump().alloc([VNode {
// VNode { parent: self.parent,
// node_id: self.node_id.clone(), template: self.template,
// parent: self.parent, root_ids: self.root_ids,
// template: self.template, key: self.key,
// root_ids: self.root_ids, dynamic_nodes: self.dynamic_nodes,
// key: self.key, dynamic_attrs: self.dynamic_attrs,
// dynamic_nodes: self.dynamic_nodes, }])))
// dynamic_attrs: self.dynamic_attrs,
// }
} }
} }
pub trait IntoTemplate<'a> { pub trait IntoTemplate<'a> {
fn into_template(self, _cx: &'a ScopeState) -> VNode<'a>; fn into_template(self, _cx: &'a ScopeState) -> VNode<'a>;
} }
impl<'a, 'b> IntoTemplate<'a> for VNode<'a> { impl<'a> IntoTemplate<'a> for VNode<'a> {
fn into_template(self, _cx: &'a ScopeState) -> VNode<'a> { fn into_template(self, _cx: &'a ScopeState) -> VNode<'a> {
self self
} }
+1 -9
View File
@@ -1,6 +1,6 @@
use crate::{arena::ElementId, ScopeId}; use crate::{arena::ElementId, ScopeId};
#[derive(Debug)] #[derive(Debug, Default)]
#[must_use = "not handling edits can lead to visual inconsistencies in UI"] #[must_use = "not handling edits can lead to visual inconsistencies in UI"]
pub struct Mutations<'a> { pub struct Mutations<'a> {
pub subtree: usize, pub subtree: usize,
@@ -9,14 +9,6 @@ pub struct Mutations<'a> {
} }
impl<'a> Mutations<'a> { impl<'a> Mutations<'a> {
pub fn new() -> Self {
Self {
subtree: 0,
edits: Vec::new(),
template_mutations: Vec::new(),
}
}
/// A useful tool for testing mutations /// A useful tool for testing mutations
/// ///
/// Rewrites IDs to just be "template", so you can compare the mutations /// Rewrites IDs to just be "template", so you can compare the mutations
+13 -11
View File
@@ -102,8 +102,8 @@ pub struct VComponent<'a> {
pub name: &'static str, pub name: &'static str,
pub static_props: bool, pub static_props: bool,
pub scope: Cell<Option<ScopeId>>, pub scope: Cell<Option<ScopeId>>,
pub props: Cell<Option<Box<dyn AnyProps<'a> + 'a>>>,
pub render_fn: *const (), pub render_fn: *const (),
pub(crate) props: Cell<Option<Box<dyn AnyProps<'a> + 'a>>>,
} }
impl<'a> std::fmt::Debug for VComponent<'a> { impl<'a> std::fmt::Debug for VComponent<'a> {
@@ -153,11 +153,13 @@ pub enum AttributeValue<'a> {
Float(f32), Float(f32),
Int(i32), Int(i32),
Bool(bool), Bool(bool),
Listener(RefCell<Option<BumpBox<'a, dyn FnMut(UiEvent<dyn Any>) + 'a>>>), Listener(RefCell<Option<ListenerCb<'a>>>),
Any(BumpBox<'a, dyn AnyValue>), Any(BumpBox<'a, dyn AnyValue>),
None, None,
} }
type ListenerCb<'a> = BumpBox<'a, dyn FnMut(UiEvent<dyn Any>) + 'a>;
impl<'a> AttributeValue<'a> { impl<'a> AttributeValue<'a> {
pub fn new_listener<T: 'static>( pub fn new_listener<T: 'static>(
cx: &'a ScopeState, cx: &'a ScopeState,
@@ -208,15 +210,15 @@ impl<'a> PartialEq for AttributeValue<'a> {
impl<'a> AttributeValue<'a> { impl<'a> AttributeValue<'a> {
pub fn matches_type(&self, other: &'a AttributeValue<'a>) -> bool { pub fn matches_type(&self, other: &'a AttributeValue<'a>) -> bool {
match (self, other) { matches!(
(Self::Text(_), Self::Text(_)) => true, (self, other),
(Self::Float(_), Self::Float(_)) => true, (Self::Text(_), Self::Text(_))
(Self::Int(_), Self::Int(_)) => true, | (Self::Float(_), Self::Float(_))
(Self::Bool(_), Self::Bool(_)) => true, | (Self::Int(_), Self::Int(_))
(Self::Listener(_), Self::Listener(_)) => true, | (Self::Bool(_), Self::Bool(_))
(Self::Any(_), Self::Any(_)) => true, | (Self::Listener(_), Self::Listener(_))
_ => return false, | (Self::Any(_), Self::Any(_))
} )
} }
} }
+1 -1
View File
@@ -41,7 +41,7 @@ impl SuspenseBoundary {
Self { Self {
id, id,
waiting_on: Default::default(), waiting_on: Default::default(),
mutations: RefCell::new(Mutations::new()), mutations: RefCell::new(Mutations::default()),
placeholder: Cell::new(None), placeholder: Cell::new(None),
created_on_stack: Cell::new(0), created_on_stack: Cell::new(0),
onresolve: None, onresolve: None,
+2 -16
View File
@@ -2,8 +2,7 @@ use super::{waker::RcWake, Scheduler, SchedulerMsg};
use crate::ScopeId; use crate::ScopeId;
use std::cell::RefCell; use std::cell::RefCell;
use std::future::Future; use std::future::Future;
use std::task::Context; use std::{pin::Pin, rc::Rc};
use std::{pin::Pin, rc::Rc, task::Poll};
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -12,22 +11,9 @@ pub struct TaskId(pub usize);
/// the task itself is the waker /// the task itself is the waker
pub(crate) struct LocalTask { pub(crate) struct LocalTask {
pub scope: ScopeId, pub scope: ScopeId,
pub(super) task: RefCell<Pin<Box<dyn Future<Output = ()> + 'static>>>,
id: TaskId, id: TaskId,
tx: futures_channel::mpsc::UnboundedSender<SchedulerMsg>, tx: futures_channel::mpsc::UnboundedSender<SchedulerMsg>,
task: RefCell<Pin<Box<dyn Future<Output = ()> + 'static>>>,
}
impl LocalTask {
/// Poll this task and return whether or not it is complete
pub(super) fn progress(self: &Rc<Self>) -> bool {
let waker = self.waker();
let mut cx = Context::from_waker(&waker);
match self.task.borrow_mut().as_mut().poll(&mut cx) {
Poll::Ready(_) => true,
_ => false,
}
}
} }
impl Scheduler { impl Scheduler {
+4 -1
View File
@@ -18,8 +18,11 @@ impl VirtualDom {
let mut tasks = self.scheduler.tasks.borrow_mut(); let mut tasks = self.scheduler.tasks.borrow_mut();
let task = &tasks[id.0]; let task = &tasks[id.0];
let waker = task.waker();
let mut cx = Context::from_waker(&waker);
// If the task completes... // If the task completes...
if task.progress() { if task.task.borrow_mut().as_mut().poll(&mut cx).is_ready() {
// Remove it from the scope so we dont try to double drop it when the scope dropes // Remove it from the scope so we dont try to double drop it when the scope dropes
self.scopes[task.scope.0].spawned_tasks.remove(&id); self.scopes[task.scope.0].spawned_tasks.remove(&id);
+2 -2
View File
@@ -134,7 +134,7 @@ impl ScopeState {
/// This is useful for traversing the tree outside of the VirtualDom, such as in a custom renderer or in SSR. /// This is useful for traversing the tree outside of the VirtualDom, such as in a custom renderer or in SSR.
/// ///
/// Panics if the tree has not been built yet. /// Panics if the tree has not been built yet.
pub fn root_node<'a>(&'a self) -> &'a RenderReturn<'a> { pub fn root_node(&self) -> &RenderReturn {
self.try_root_node() self.try_root_node()
.expect("The tree has not been built yet. Make sure to call rebuild on the tree before accessing its nodes.") .expect("The tree has not been built yet. Make sure to call rebuild on the tree before accessing its nodes.")
} }
@@ -144,7 +144,7 @@ impl ScopeState {
/// This is useful for traversing the tree outside of the VirtualDom, such as in a custom renderer or in SSR. /// This is useful for traversing the tree outside of the VirtualDom, such as in a custom renderer or in SSR.
/// ///
/// Returns [`None`] if the tree has not been built yet. /// Returns [`None`] if the tree has not been built yet.
pub fn try_root_node<'a>(&'a self) -> Option<&'a RenderReturn<'a>> { pub fn try_root_node(&self) -> Option<&RenderReturn> {
let ptr = self.current_frame().node.get(); let ptr = self.current_frame().node.get();
if ptr.is_null() { if ptr.is_null() {
+6 -9
View File
@@ -6,7 +6,7 @@ use crate::{
any_props::VProps, any_props::VProps,
arena::{ElementId, ElementRef}, arena::{ElementId, ElementRef},
factory::RenderReturn, factory::RenderReturn,
innerlude::{DirtyScope, Mutations, Scheduler, SchedulerMsg, ErrorBoundary}, innerlude::{DirtyScope, ErrorBoundary, Mutations, Scheduler, SchedulerMsg},
mutations::Mutation, mutations::Mutation,
nodes::{Template, TemplateId}, nodes::{Template, TemplateId},
scheduler::{SuspenseBoundary, SuspenseId}, scheduler::{SuspenseBoundary, SuspenseId},
@@ -236,7 +236,7 @@ impl VirtualDom {
dirty_scopes: BTreeSet::new(), dirty_scopes: BTreeSet::new(),
collected_leaves: Vec::new(), collected_leaves: Vec::new(),
finished_fibers: Vec::new(), finished_fibers: Vec::new(),
mutations: Mutations::new(), mutations: Mutations::default(),
}; };
let root = dom.new_scope(Box::new(VProps::new( let root = dom.new_scope(Box::new(VProps::new(
@@ -454,9 +454,9 @@ impl VirtualDom {
} }
/// Swap the current mutations with a new /// Swap the current mutations with a new
fn finalize<'a>(&'a mut self) -> Mutations<'a> { fn finalize(&mut self) -> Mutations {
// todo: make this a routine // todo: make this a routine
let mut out = Mutations::new(); let mut out = Mutations::default();
std::mem::swap(&mut self.mutations, &mut out); std::mem::swap(&mut self.mutations, &mut out);
out out
} }
@@ -481,7 +481,7 @@ impl VirtualDom {
/// ///
/// apply_edits(edits); /// apply_edits(edits);
/// ``` /// ```
pub fn rebuild<'a>(&'a mut self) -> Mutations<'a> { pub fn rebuild(&mut self) -> Mutations {
match unsafe { self.run_scope(ScopeId(0)).extend_lifetime_ref() } { match unsafe { self.run_scope(ScopeId(0)).extend_lifetime_ref() } {
// Rebuilding implies we append the created elements to the root // Rebuilding implies we append the created elements to the root
RenderReturn::Sync(Ok(node)) => { RenderReturn::Sync(Ok(node)) => {
@@ -519,10 +519,7 @@ impl VirtualDom {
/// It's generally a good idea to put some sort of limit on the suspense process in case a future is having issues. /// It's generally a good idea to put some sort of limit on the suspense process in case a future is having issues.
/// ///
/// If no suspense trees are present /// If no suspense trees are present
pub async fn render_with_deadline<'a>( pub async fn render_with_deadline(&mut self, deadline: impl Future<Output = ()>) -> Mutations {
&'a mut self,
deadline: impl Future<Output = ()>,
) -> Mutations<'a> {
pin_mut!(deadline); pin_mut!(deadline);
loop { loop {