1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
use syn::{Expr, ExprPath, Lit}; /// Node in the tree #[derive(Debug)] pub struct Node { /// Content depends on the `NodeType`: /// /// - `Element`: name of the tag /// - `Attribute`: key of the attribute /// - `Text`: `None` /// - `Block`: `None` pub name: Option<ExprPath>, /// Type of the node pub node_type: NodeType, /// Holds a value according to the `NodeType` pub value: Option<Expr>, /// Only might have nodes if `NodeType::Element`. Holds every attribute /// as `NodeType::Attribute` pub attributes: Vec<Node>, /// Only might have nodes if `NodeType::Element`. Holds every child as /// `Node` pub children: Vec<Node>, } impl Node { /// Returns `node_name` path as `String` pub fn name_as_string(&self) -> Option<String> { match self.name.as_ref() { Some(ExprPath { path, .. }) => Some( path.segments .iter() .map(|segment| segment.ident.to_string()) .collect::<Vec<String>>() .join("::"), ), _ => None, } } /// Returns `node_value` as `String` if the value is a `Lit::Str` expression pub fn value_as_string(&self) -> Option<String> { match self.value.as_ref() { Some(Expr::Lit(expr)) => match &expr.lit { Lit::Str(lit_str) => Some(lit_str.value()), _ => None, }, _ => None, } } } /// Type of the Node #[derive(Debug)] pub enum NodeType { /// A HTMLElement tag, with optional children and attributes. /// Potentially selfclosing. Any tag name is valid. Element, /// Attributes of opening tags. Every attribute is itself a node. Attribute, /// Quoted text. It's planned to support unquoted text as well /// using span start and end, but that currently only works /// with nightly rust Text, /// Arbitrary rust code in braced `{}` blocks Block, }