1111extern  crate  html5ever; 
1212
1313use  std:: borrow:: Cow ; 
14+ use  std:: cell:: { Cell ,  RefCell } ; 
1415use  std:: collections:: HashMap ; 
1516use  std:: io; 
1617
@@ -20,14 +21,14 @@ use html5ever::tree_builder::{ElementFlags, NodeOrText, QuirksMode, TreeSink};
2021use  html5ever:: { Attribute ,  ExpandedName ,  QualName } ; 
2122
2223struct  Sink  { 
23-     next_id :  usize , 
24-     names :  HashMap < usize ,  QualName > , 
24+     next_id :  Cell < usize > , 
25+     names :  RefCell < HashMap < usize ,  & ' static   QualName > > , 
2526} 
2627
2728impl  Sink  { 
28-     fn  get_id ( & mut   self )  -> usize  { 
29-         let  id = self . next_id ; 
30-         self . next_id  +=  2 ; 
29+     fn  get_id ( & self )  -> usize  { 
30+         let  id = self . next_id . get ( ) ; 
31+         self . next_id . set ( id +  2 ) ; 
3132        id
3233    } 
3334} 
@@ -43,12 +44,13 @@ impl TreeSink for Sink {
4344        self 
4445    } 
4546
46-     fn  get_document ( & mut   self )  -> usize  { 
47+     fn  get_document ( & self )  -> usize  { 
4748        0 
4849    } 
4950
50-     fn  get_template_contents ( & mut  self ,  target :  & usize )  -> usize  { 
51-         if  let  Some ( expanded_name ! ( html "template" ) )  = self . names . get ( target) . map ( |n| n. expanded ( ) ) 
51+     fn  get_template_contents ( & self ,  target :  & usize )  -> usize  { 
52+         if  let  Some ( expanded_name ! ( html "template" ) )  =
53+             self . names . borrow ( ) . get ( target) . map ( |n| n. expanded ( ) ) 
5254        { 
5355            target + 1 
5456        }  else  { 
@@ -61,53 +63,63 @@ impl TreeSink for Sink {
6163    } 
6264
6365    fn  elem_name ( & self ,  target :  & usize )  -> ExpandedName  { 
64-         self . names . get ( target) . expect ( "not an element" ) . expanded ( ) 
66+         self . names 
67+             . borrow ( ) 
68+             . get ( target) 
69+             . expect ( "not an element" ) 
70+             . expanded ( ) 
6571    } 
6672
67-     fn  create_element ( & mut   self ,  name :  QualName ,  _:  Vec < Attribute > ,  _:  ElementFlags )  -> usize  { 
73+     fn  create_element ( & self ,  name :  QualName ,  _:  Vec < Attribute > ,  _:  ElementFlags )  -> usize  { 
6874        let  id = self . get_id ( ) ; 
69-         self . names . insert ( id,  name) ; 
75+         // N.B. We intentionally leak memory here to minimize the implementation complexity 
76+         //      of this example code. A real implementation would either want to use a real 
77+         //      real DOM tree implentation, or else use an arena as the backing store for 
78+         //      memory used by the parser. 
79+         self . names 
80+             . borrow_mut ( ) 
81+             . insert ( id,  Box :: leak ( Box :: new ( name) ) ) ; 
7082        id
7183    } 
7284
73-     fn  create_comment ( & mut   self ,  _text :  StrTendril )  -> usize  { 
85+     fn  create_comment ( & self ,  _text :  StrTendril )  -> usize  { 
7486        self . get_id ( ) 
7587    } 
7688
7789    #[ allow( unused_variables) ]  
78-     fn  create_pi ( & mut   self ,  target :  StrTendril ,  value :  StrTendril )  -> usize  { 
90+     fn  create_pi ( & self ,  target :  StrTendril ,  value :  StrTendril )  -> usize  { 
7991        unimplemented ! ( ) 
8092    } 
8193
82-     fn  append_before_sibling ( & mut   self ,  _sibling :  & usize ,  _new_node :  NodeOrText < usize > )  { } 
94+     fn  append_before_sibling ( & self ,  _sibling :  & usize ,  _new_node :  NodeOrText < usize > )  { } 
8395
8496    fn  append_based_on_parent_node ( 
85-         & mut   self , 
97+         & self , 
8698        _element :  & usize , 
8799        _prev_element :  & usize , 
88100        _new_node :  NodeOrText < usize > , 
89101    )  { 
90102    } 
91103
92-     fn  parse_error ( & mut   self ,  _msg :  Cow < ' static ,  str > )  { } 
93-     fn  set_quirks_mode ( & mut   self ,  _mode :  QuirksMode )  { } 
94-     fn  append ( & mut   self ,  _parent :  & usize ,  _child :  NodeOrText < usize > )  { } 
104+     fn  parse_error ( & self ,  _msg :  Cow < ' static ,  str > )  { } 
105+     fn  set_quirks_mode ( & self ,  _mode :  QuirksMode )  { } 
106+     fn  append ( & self ,  _parent :  & usize ,  _child :  NodeOrText < usize > )  { } 
95107
96-     fn  append_doctype_to_document ( & mut   self ,  _:  StrTendril ,  _:  StrTendril ,  _:  StrTendril )  { } 
97-     fn  add_attrs_if_missing ( & mut   self ,  target :  & usize ,  _attrs :  Vec < Attribute > )  { 
98-         assert ! ( self . names. contains_key( target) ,  "not an element" ) ; 
108+     fn  append_doctype_to_document ( & self ,  _:  StrTendril ,  _:  StrTendril ,  _:  StrTendril )  { } 
109+     fn  add_attrs_if_missing ( & self ,  target :  & usize ,  _attrs :  Vec < Attribute > )  { 
110+         assert ! ( self . names. borrow ( ) . contains_key( target) ,  "not an element" ) ; 
99111    } 
100-     fn  remove_from_parent ( & mut   self ,  _target :  & usize )  { } 
101-     fn  reparent_children ( & mut   self ,  _node :  & usize ,  _new_parent :  & usize )  { } 
102-     fn  mark_script_already_started ( & mut   self ,  _node :  & usize )  { } 
112+     fn  remove_from_parent ( & self ,  _target :  & usize )  { } 
113+     fn  reparent_children ( & self ,  _node :  & usize ,  _new_parent :  & usize )  { } 
114+     fn  mark_script_already_started ( & self ,  _node :  & usize )  { } 
103115} 
104116
105117/// In this example we implement the TreeSink trait which takes each parsed elements and insert 
106118/// it to a hashmap, while each element is given a numeric id. 
107119fn  main ( )  { 
108120    let  sink = Sink  { 
109-         next_id :  1 , 
110-         names :  HashMap :: new ( ) , 
121+         next_id :  Cell :: new ( 1 ) , 
122+         names :  RefCell :: new ( HashMap :: new ( ) ) , 
111123    } ; 
112124
113125    // Read HTML from the standard input and parse it 
0 commit comments