mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
chore(leptos_hot_reload): apply lints suggestions (#1735)
This commit is contained in:
parent
1d392483b4
commit
6cc92cee8d
4 changed files with 50 additions and 29 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>();
|
||||||
|
|
||||||
|
|
|
@ -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())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue