Topus

相较javascriptrust有更加严谨的语法,编译期能发现bug的优点。既然javascript能写html,是不是用rusthtml体验更好。基于此想法,我写了topus

我的想法是

  1. 构建一个简单struct DOM,由上至下有enum Nodeenum Attribute
  2. 实现Display trait,通过to_string()转换成字符串
  3. 创建html文件,写入字符串

Attribute

为了减少学习难度,所有字符串类型为String,而不是带有生命周期的&str

enum Attribute有两个attribute变种。

  1. Boolean(String),代表布尔属性,如hidden。
  2. Normal { key: String, value: Sting },代表普通属性,如style="display: None"

创建方式

  1. 直接创建

rust let hidden = Attribute::Boolean("hidden".to_string()); let style = Attribute::Normal { key: "style".to_string(), value: "display: None".to_string() }; let http_equiv = Attribute::Normal { key: "http-equiv".to_string(), value: "X-UA-Compatible".to_string() };

  1. 宏创建

rust let macro_hidden = attribute!(hidden); let macro_style = attribute!(style="display: None"); let macro_http_equiv = attribute!(http-equiv="X-UA-Compatible");

推荐使用宏创建Attribute,方便快捷。

断言

rust assert_eq!(hidden, macro_hidden); assert_eq!(style, macro_style); assert_eq!(http_equiv, macro_http_equiv);

创建Vec

使用attributes宏可以很方便的创建Vec

rust let attributes = attributes!(html style="display:None"); assert_eq!( vec![ Attribute::Normal{ key: "style".to_string(), value: "display:None".to_string() }, Attribute::Boolean("html".to_string())], attrs);

细心的应该发现问题了,htmlstyle="display:None" 属性是逆向加入Vec容器的。

Node

enum Node有三个变种。

  1. Element { node_name: String, attributes: Vec<Attribute>, child_nodes: Vec<Node>},代表element node
  2. Text { node_value: String },代表text node
  3. Comment { node_value: String },代表comment node

创建方式

  1. 直接创建

``` rust let text = Node::Text { nodevalue: "hello world".tostring() } let comment = Node::Comment { nodevalue: "comment".tostring()}

let doctype = Node::Element { nodename: "!DOCTYPE".tostring(), attributes: attributes!(html), childnodes: Vec::::withcapacity(0) }; let a = Node::Element { nodename: "a".tostring(), attributes: attributes!(hidden style="display:None"), childnodes: Vec::::withcapacity(0) }; ```

  1. 宏创建

``` rust let macrotext = text!("hello world"); let macrocomment = comment!("comment");

let macrodoctype = element!(!DOCTYPE html); let macroa = element!(a hidden style="display:None"); ```

断言

``` rust asserteq!(text, macrotext); asserteq!(comment, macrocomment); asserteq!(doctype, macrodoctype);

asserteq!(a, macroa); asserteq!("