chore(leptos_hot_reload): apply lints suggestions (#1735)

This commit is contained in:
Fangdun Tsai 2023-09-23 01:48:23 +08:00 committed by GitHub
parent 1d392483b4
commit 6cc92cee8d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 29 deletions

View file

@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
struct OldChildren(IndexMap<LNode, Vec<usize>>); struct OldChildren(IndexMap<LNode, Vec<usize>>);
impl LNode { impl LNode {
#[must_use]
pub fn diff(&self, other: &LNode) -> Vec<Patch> { pub fn diff(&self, other: &LNode) -> Vec<Patch> {
let mut old_children = OldChildren::default(); let mut old_children = OldChildren::default();
self.add_old_children(vec![], &mut old_children); self.add_old_children(vec![], &mut old_children);
@ -196,7 +197,7 @@ impl LNode {
if replace { if replace {
match &new_value { match &new_value {
LAttributeValue::Boolean => { LAttributeValue::Boolean => {
Some((name.to_owned(), "".to_string())) Some((name.to_owned(), String::new()))
} }
LAttributeValue::Static(s) => { LAttributeValue::Static(s) => {
Some((name.to_owned(), s.to_owned())) Some((name.to_owned(), s.to_owned()))
@ -213,13 +214,13 @@ impl LNode {
}); });
let removals = old.iter().filter_map(|(name, _)| { let removals = old.iter().filter_map(|(name, _)| {
if !new.iter().any(|(new_name, _)| new_name == name) { if new.iter().any(|(new_name, _)| new_name == name) {
None
} else {
Some(Patch { Some(Patch {
path: path.to_owned(), path: path.to_owned(),
action: PatchAction::RemoveAttribute(name.to_owned()), action: PatchAction::RemoveAttribute(name.to_owned()),
}) })
} else {
None
} }
}); });
@ -259,7 +260,6 @@ impl LNode {
let new = new.get(a); let new = new.get(a);
match (old, new) { match (old, new) {
(None, None) => {}
(None, Some(new)) => patches.push(Patch { (None, Some(new)) => patches.push(Patch {
path: path.to_owned(), path: path.to_owned(),
action: PatchAction::InsertChild { action: PatchAction::InsertChild {
@ -271,11 +271,10 @@ impl LNode {
path: path.to_owned(), path: path.to_owned(),
action: PatchAction::RemoveChild { at: a }, action: PatchAction::RemoveChild { at: a },
}), }),
(Some(old), Some(new)) => { (Some(old), Some(new)) if old != new => {
if old != new { break;
break;
}
} }
_ => {}
} }
a += 1; a += 1;
@ -287,7 +286,6 @@ impl LNode {
let new = new.get(b); let new = new.get(b);
match (old, new) { match (old, new) {
(None, None) => {}
(None, Some(new)) => patches.push(Patch { (None, Some(new)) => patches.push(Patch {
path: path.to_owned(), path: path.to_owned(),
action: PatchAction::InsertChildAfter { action: PatchAction::InsertChildAfter {
@ -299,18 +297,16 @@ impl LNode {
path: path.to_owned(), path: path.to_owned(),
action: PatchAction::RemoveChild { at: b }, action: PatchAction::RemoveChild { at: b },
}), }),
(Some(old), Some(new)) => { (Some(old), Some(new)) if old != new => {
if old != new { break;
break;
}
} }
_ => {}
} }
if b == 0 { if b == 0 {
break; break;
} else {
b -= 1;
} }
b -= 1;
} }
// diffing in middle // diffing in middle

View file

@ -33,10 +33,14 @@ pub struct ViewMacros {
} }
impl ViewMacros { impl ViewMacros {
#[must_use]
pub fn new() -> Self { pub fn new() -> Self {
Self::default() Self::default()
} }
/// # Errors
///
/// Will return `Err` if the path is not UTF-8 path or the contents of the file cannot be parsed.
pub fn update_from_paths<T: AsRef<Path>>(&self, paths: &[T]) -> Result<()> { pub fn update_from_paths<T: AsRef<Path>>(&self, paths: &[T]) -> Result<()> {
let mut views = HashMap::new(); let mut views = HashMap::new();
@ -59,6 +63,9 @@ impl ViewMacros {
Ok(()) Ok(())
} }
/// # Errors
///
/// Will return `Err` if the contents of the file cannot be parsed.
pub fn parse_file(path: &Utf8PathBuf) -> Result<Vec<MacroInvocation>> { pub fn parse_file(path: &Utf8PathBuf) -> Result<Vec<MacroInvocation>> {
let mut file = File::open(path)?; let mut file = File::open(path)?;
let mut content = String::new(); let mut content = String::new();
@ -76,11 +83,14 @@ impl ViewMacros {
let rsx = let rsx =
rstml::parse2(tokens.collect::<proc_macro2::TokenStream>())?; rstml::parse2(tokens.collect::<proc_macro2::TokenStream>())?;
let template = LNode::parse_view(rsx)?; let template = LNode::parse_view(rsx)?;
views.push(MacroInvocation { id, template }) views.push(MacroInvocation { id, template });
} }
Ok(views) Ok(views)
} }
/// # Errors
///
/// Will return `Err` if the contents of the file cannot be parsed.
pub fn patch(&self, path: &Utf8PathBuf) -> Result<Option<Patches>> { pub fn patch(&self, path: &Utf8PathBuf) -> Result<Option<Patches>> {
let new_views = Self::parse_file(path)?; let new_views = Self::parse_file(path)?;
let mut lock = self.views.write(); let mut lock = self.views.write();
@ -125,7 +135,7 @@ impl std::fmt::Debug for MacroInvocation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MacroInvocation") f.debug_struct("MacroInvocation")
.field("id", &self.id) .field("id", &self.id)
.finish() .finish_non_exhaustive()
} }
} }
@ -136,7 +146,7 @@ pub struct ViewMacroVisitor<'a> {
impl<'ast> Visit<'ast> for ViewMacroVisitor<'ast> { impl<'ast> Visit<'ast> for ViewMacroVisitor<'ast> {
fn visit_macro(&mut self, node: &'ast Macro) { fn visit_macro(&mut self, node: &'ast Macro) {
let ident = node.path.get_ident().map(|n| n.to_string()); let ident = node.path.get_ident().map(ToString::to_string);
if ident == Some("view".to_string()) { if ident == Some("view".to_string()) {
self.views.push(node); self.views.push(node);
} }

View file

@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize};
// `syn` types are `!Send` so we can't store them as we might like. // `syn` types are `!Send` so we can't store them as we might like.
// This is only used to diff view macros for hot reloading so it's very minimal // This is only used to diff view macros for hot reloading so it's very minimal
// and ignores many of the data types. // and ignores many of the data types.
#[allow(clippy::module_name_repetitions)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum LNode { pub enum LNode {
Fragment(Vec<LNode>), Fragment(Vec<LNode>),
@ -38,18 +39,26 @@ pub enum LAttributeValue {
} }
impl LNode { impl LNode {
/// # Errors
///
/// Will return `Err` if parsing the view fails.
pub fn parse_view(nodes: Vec<Node>) -> Result<LNode> { pub fn parse_view(nodes: Vec<Node>) -> Result<LNode> {
let mut out = Vec::new(); let mut out = Vec::new();
for node in nodes { for node in nodes {
LNode::parse_node(node, &mut out)?; LNode::parse_node(node, &mut out)?;
} }
if out.len() == 1 { if out.len() == 1 {
Ok(out.pop().unwrap()) out.pop().ok_or_else(|| {
unreachable!("The last element should not be None.")
})
} else { } else {
Ok(LNode::Fragment(out)) Ok(LNode::Fragment(out))
} }
} }
/// # Errors
///
/// Will return `Err` if parsing the node fails.
pub fn parse_node(node: Node, views: &mut Vec<LNode>) -> Result<()> { pub fn parse_node(node: Node, views: &mut Vec<LNode>) -> Result<()> {
match node { match node {
Node::Fragment(frag) => { Node::Fragment(frag) => {
@ -61,9 +70,9 @@ impl LNode {
views.push(LNode::Text(text.value_string())); views.push(LNode::Text(text.value_string()));
} }
Node::Block(block) => { Node::Block(block) => {
let code = block.into_token_stream(); views.push(LNode::DynChild(
let code = code.to_string(); block.into_token_stream().to_string(),
views.push(LNode::DynChild(code)); ));
} }
Node::Element(el) => { Node::Element(el) => {
if is_component_node(&el) { if is_component_node(&el) {
@ -83,7 +92,7 @@ impl LNode {
attr.key.to_string(), attr.key.to_string(),
format!("{:#?}", attr.value()), format!("{:#?}", attr.value()),
)), )),
_ => None, NodeAttribute::Block(_) => None,
}) })
.collect(), .collect(),
children, children,
@ -151,8 +160,9 @@ impl LNode {
LAttributeValue::Static(value) => { LAttributeValue::Static(value) => {
Some(format!("{name}=\"{value}\" ")) Some(format!("{name}=\"{value}\" "))
} }
LAttributeValue::Dynamic => None, LAttributeValue::Dynamic | LAttributeValue::Noop => {
LAttributeValue::Noop => None, None
}
}) })
.collect::<String>(); .collect::<String>();

View file

@ -1,6 +1,5 @@
use rstml::node::{NodeElement, NodeName}; use rstml::node::{NodeElement, NodeName};
///
/// Converts `syn::Block` to simple expression /// Converts `syn::Block` to simple expression
/// ///
/// For example: /// For example:
@ -14,6 +13,7 @@ use rstml::node::{NodeElement, NodeName};
/// // variable /// // variable
/// {path::x} /// {path::x}
/// ``` /// ```
#[must_use]
pub fn block_to_primitive_expression(block: &syn::Block) -> Option<&syn::Expr> { pub fn block_to_primitive_expression(block: &syn::Block) -> Option<&syn::Expr> {
// its empty block, or block with multi lines // its empty block, or block with multi lines
if block.stmts.len() != 1 { if block.stmts.len() != 1 {
@ -29,6 +29,7 @@ pub fn block_to_primitive_expression(block: &syn::Block) -> Option<&syn::Expr> {
/// ///
/// This function doesn't convert literal wrapped inside block /// This function doesn't convert literal wrapped inside block
/// like: `{"string"}`. /// like: `{"string"}`.
#[must_use]
pub fn value_to_string(value: &syn::Expr) -> Option<String> { pub fn value_to_string(value: &syn::Expr) -> Option<String> {
match &value { match &value {
syn::Expr::Lit(lit) => match &lit.lit { syn::Expr::Lit(lit) => match &lit.lit {
@ -42,6 +43,10 @@ pub fn value_to_string(value: &syn::Expr) -> Option<String> {
} }
} }
/// # Panics
///
/// Will panic if the last element does not exist in the path.
#[must_use]
pub fn is_component_tag_name(name: &NodeName) -> bool { pub fn is_component_tag_name(name: &NodeName) -> bool {
match name { match name {
NodeName::Path(path) => { NodeName::Path(path) => {
@ -55,11 +60,11 @@ pub fn is_component_tag_name(name: &NodeName) -> bool {
.to_string() .to_string()
.starts_with(|c: char| c.is_ascii_uppercase()) .starts_with(|c: char| c.is_ascii_uppercase())
} }
NodeName::Block(_) => false, NodeName::Block(_) | NodeName::Punctuated(_) => false,
NodeName::Punctuated(_) => false,
} }
} }
#[must_use]
pub fn is_component_node(node: &NodeElement) -> bool { pub fn is_component_node(node: &NodeElement) -> bool {
is_component_tag_name(node.name()) is_component_tag_name(node.name())
} }