mirror of
https://github.com/leptos-rs/leptos
synced 2024-09-20 06:21:57 +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>>);
|
||||
|
||||
impl LNode {
|
||||
#[must_use]
|
||||
pub fn diff(&self, other: &LNode) -> Vec<Patch> {
|
||||
let mut old_children = OldChildren::default();
|
||||
self.add_old_children(vec![], &mut old_children);
|
||||
|
@ -196,7 +197,7 @@ impl LNode {
|
|||
if replace {
|
||||
match &new_value {
|
||||
LAttributeValue::Boolean => {
|
||||
Some((name.to_owned(), "".to_string()))
|
||||
Some((name.to_owned(), String::new()))
|
||||
}
|
||||
LAttributeValue::Static(s) => {
|
||||
Some((name.to_owned(), s.to_owned()))
|
||||
|
@ -213,13 +214,13 @@ impl LNode {
|
|||
});
|
||||
|
||||
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 {
|
||||
path: path.to_owned(),
|
||||
action: PatchAction::RemoveAttribute(name.to_owned()),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -259,7 +260,6 @@ impl LNode {
|
|||
let new = new.get(a);
|
||||
|
||||
match (old, new) {
|
||||
(None, None) => {}
|
||||
(None, Some(new)) => patches.push(Patch {
|
||||
path: path.to_owned(),
|
||||
action: PatchAction::InsertChild {
|
||||
|
@ -271,11 +271,10 @@ impl LNode {
|
|||
path: path.to_owned(),
|
||||
action: PatchAction::RemoveChild { at: a },
|
||||
}),
|
||||
(Some(old), Some(new)) => {
|
||||
if old != new {
|
||||
break;
|
||||
}
|
||||
(Some(old), Some(new)) if old != new => {
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
a += 1;
|
||||
|
@ -287,7 +286,6 @@ impl LNode {
|
|||
let new = new.get(b);
|
||||
|
||||
match (old, new) {
|
||||
(None, None) => {}
|
||||
(None, Some(new)) => patches.push(Patch {
|
||||
path: path.to_owned(),
|
||||
action: PatchAction::InsertChildAfter {
|
||||
|
@ -299,18 +297,16 @@ impl LNode {
|
|||
path: path.to_owned(),
|
||||
action: PatchAction::RemoveChild { at: b },
|
||||
}),
|
||||
(Some(old), Some(new)) => {
|
||||
if old != new {
|
||||
break;
|
||||
}
|
||||
(Some(old), Some(new)) if old != new => {
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if b == 0 {
|
||||
break;
|
||||
} else {
|
||||
b -= 1;
|
||||
}
|
||||
b -= 1;
|
||||
}
|
||||
|
||||
// diffing in middle
|
||||
|
|
|
@ -33,10 +33,14 @@ pub struct ViewMacros {
|
|||
}
|
||||
|
||||
impl ViewMacros {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
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<()> {
|
||||
let mut views = HashMap::new();
|
||||
|
||||
|
@ -59,6 +63,9 @@ impl ViewMacros {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
///
|
||||
/// Will return `Err` if the contents of the file cannot be parsed.
|
||||
pub fn parse_file(path: &Utf8PathBuf) -> Result<Vec<MacroInvocation>> {
|
||||
let mut file = File::open(path)?;
|
||||
let mut content = String::new();
|
||||
|
@ -76,11 +83,14 @@ impl ViewMacros {
|
|||
let rsx =
|
||||
rstml::parse2(tokens.collect::<proc_macro2::TokenStream>())?;
|
||||
let template = LNode::parse_view(rsx)?;
|
||||
views.push(MacroInvocation { id, template })
|
||||
views.push(MacroInvocation { id, template });
|
||||
}
|
||||
Ok(views)
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
///
|
||||
/// Will return `Err` if the contents of the file cannot be parsed.
|
||||
pub fn patch(&self, path: &Utf8PathBuf) -> Result<Option<Patches>> {
|
||||
let new_views = Self::parse_file(path)?;
|
||||
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 {
|
||||
f.debug_struct("MacroInvocation")
|
||||
.field("id", &self.id)
|
||||
.finish()
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,7 +146,7 @@ pub struct ViewMacroVisitor<'a> {
|
|||
|
||||
impl<'ast> Visit<'ast> for ViewMacroVisitor<'ast> {
|
||||
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()) {
|
||||
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.
|
||||
// This is only used to diff view macros for hot reloading so it's very minimal
|
||||
// and ignores many of the data types.
|
||||
#[allow(clippy::module_name_repetitions)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum LNode {
|
||||
Fragment(Vec<LNode>),
|
||||
|
@ -38,18 +39,26 @@ pub enum LAttributeValue {
|
|||
}
|
||||
|
||||
impl LNode {
|
||||
/// # Errors
|
||||
///
|
||||
/// Will return `Err` if parsing the view fails.
|
||||
pub fn parse_view(nodes: Vec<Node>) -> Result<LNode> {
|
||||
let mut out = Vec::new();
|
||||
for node in nodes {
|
||||
LNode::parse_node(node, &mut out)?;
|
||||
}
|
||||
if out.len() == 1 {
|
||||
Ok(out.pop().unwrap())
|
||||
out.pop().ok_or_else(|| {
|
||||
unreachable!("The last element should not be None.")
|
||||
})
|
||||
} else {
|
||||
Ok(LNode::Fragment(out))
|
||||
}
|
||||
}
|
||||
|
||||
/// # Errors
|
||||
///
|
||||
/// Will return `Err` if parsing the node fails.
|
||||
pub fn parse_node(node: Node, views: &mut Vec<LNode>) -> Result<()> {
|
||||
match node {
|
||||
Node::Fragment(frag) => {
|
||||
|
@ -61,9 +70,9 @@ impl LNode {
|
|||
views.push(LNode::Text(text.value_string()));
|
||||
}
|
||||
Node::Block(block) => {
|
||||
let code = block.into_token_stream();
|
||||
let code = code.to_string();
|
||||
views.push(LNode::DynChild(code));
|
||||
views.push(LNode::DynChild(
|
||||
block.into_token_stream().to_string(),
|
||||
));
|
||||
}
|
||||
Node::Element(el) => {
|
||||
if is_component_node(&el) {
|
||||
|
@ -83,7 +92,7 @@ impl LNode {
|
|||
attr.key.to_string(),
|
||||
format!("{:#?}", attr.value()),
|
||||
)),
|
||||
_ => None,
|
||||
NodeAttribute::Block(_) => None,
|
||||
})
|
||||
.collect(),
|
||||
children,
|
||||
|
@ -151,8 +160,9 @@ impl LNode {
|
|||
LAttributeValue::Static(value) => {
|
||||
Some(format!("{name}=\"{value}\" "))
|
||||
}
|
||||
LAttributeValue::Dynamic => None,
|
||||
LAttributeValue::Noop => None,
|
||||
LAttributeValue::Dynamic | LAttributeValue::Noop => {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<String>();
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use rstml::node::{NodeElement, NodeName};
|
||||
|
||||
///
|
||||
/// Converts `syn::Block` to simple expression
|
||||
///
|
||||
/// For example:
|
||||
|
@ -14,6 +13,7 @@ use rstml::node::{NodeElement, NodeName};
|
|||
/// // variable
|
||||
/// {path::x}
|
||||
/// ```
|
||||
#[must_use]
|
||||
pub fn block_to_primitive_expression(block: &syn::Block) -> Option<&syn::Expr> {
|
||||
// its empty block, or block with multi lines
|
||||
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
|
||||
/// like: `{"string"}`.
|
||||
#[must_use]
|
||||
pub fn value_to_string(value: &syn::Expr) -> Option<String> {
|
||||
match &value {
|
||||
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 {
|
||||
match name {
|
||||
NodeName::Path(path) => {
|
||||
|
@ -55,11 +60,11 @@ pub fn is_component_tag_name(name: &NodeName) -> bool {
|
|||
.to_string()
|
||||
.starts_with(|c: char| c.is_ascii_uppercase())
|
||||
}
|
||||
NodeName::Block(_) => false,
|
||||
NodeName::Punctuated(_) => false,
|
||||
NodeName::Block(_) | NodeName::Punctuated(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_component_node(node: &NodeElement) -> bool {
|
||||
is_component_tag_name(node.name())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue