Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(leptos_hot_reload): apply lints suggestions #1735

Merged
merged 2 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 12 additions & 16 deletions leptos_hot_reload/src/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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()))
Expand All @@ -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
}
});

Expand Down Expand Up @@ -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 {
Expand All @@ -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;
Expand All @@ -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 {
Expand All @@ -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
Expand Down
16 changes: 13 additions & 3 deletions leptos_hot_reload/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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();
Expand All @@ -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();
Expand Down Expand Up @@ -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()
}
}

Expand All @@ -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);
}
Expand Down
24 changes: 17 additions & 7 deletions leptos_hot_reload/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>),
Expand Down Expand Up @@ -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) => {
Expand All @@ -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) {
Expand All @@ -83,7 +92,7 @@ impl LNode {
attr.key.to_string(),
format!("{:#?}", attr.value()),
)),
_ => None,
NodeAttribute::Block(_) => None,
})
.collect(),
children,
Expand Down Expand Up @@ -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>();

Expand Down
11 changes: 8 additions & 3 deletions leptos_hot_reload/src/parsing.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use rstml::node::{NodeElement, NodeName};

///
/// Converts `syn::Block` to simple expression
///
/// For example:
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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) => {
Expand All @@ -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())
}