@@ -12,13 +12,19 @@ use rustler::{
12
12
NifEnv ,
13
13
NifTerm ,
14
14
NifResult ,
15
+ NifError ,
15
16
NifEncoder ,
17
+ NifDecoder ,
16
18
} ;
17
19
use rustler:: types:: binary:: NifBinary ;
18
20
use rustler:: env:: OwnedEnv ;
19
21
20
22
use html5ever:: { QualName } ;
21
23
use html5ever:: rcdom:: { RcDom , Handle , NodeEnum } ;
24
+ use html5ever:: driver:: ParseOpts ;
25
+ use html5ever:: tokenizer:: TokenizerOpts ;
26
+ use html5ever:: tree_builder:: TreeBuilderOpts ;
27
+ use html5ever:: tree_builder:: interface:: QuirksMode ;
22
28
use tendril:: { TendrilSink , StrTendril } ;
23
29
24
30
mod atoms {
@@ -27,10 +33,74 @@ mod atoms {
27
33
28
34
atom ok;
29
35
atom error;
36
+ atom nil;
30
37
atom nif_panic;
31
38
32
39
atom doctype;
33
40
atom comment;
41
+
42
+ atom error_level;
43
+ atom discard_bom;
44
+ atom scripting_enabled;
45
+ atom iframe_srcdoc;
46
+ atom drop_doctype;
47
+
48
+ atom none;
49
+ atom some;
50
+ atom all;
51
+ }
52
+ }
53
+
54
+ #[ derive( PartialEq , Eq ) ]
55
+ enum ErrorLevel {
56
+ None ,
57
+ Some ,
58
+ All ,
59
+ }
60
+ impl < ' a > NifDecoder < ' a > for ErrorLevel {
61
+ fn decode ( term : NifTerm < ' a > ) -> NifResult < ErrorLevel > {
62
+ if atoms:: none ( ) == term { Ok ( ErrorLevel :: None ) }
63
+ else if atoms:: some ( ) == term { Ok ( ErrorLevel :: Some ) }
64
+ else if atoms:: all ( ) == term { Ok ( ErrorLevel :: All ) }
65
+ else { Err ( NifError :: BadArg ) }
66
+ }
67
+ }
68
+
69
+ fn term_to_configs ( term : NifTerm ) -> NifResult < ParseOpts > {
70
+ if atoms:: nil ( ) == term {
71
+ Ok ( ParseOpts :: default ( ) )
72
+ } else {
73
+ let env = term. get_env ( ) ;
74
+
75
+ let errors: ErrorLevel =
76
+ term. map_get ( atoms:: error_level ( ) . to_term ( env) ) ?. decode ( ) ?;
77
+
78
+ let discard_bom: bool =
79
+ term. map_get ( atoms:: discard_bom ( ) . to_term ( env) ) ?. decode ( ) ?;
80
+ let scripting_enabled: bool =
81
+ term. map_get ( atoms:: scripting_enabled ( ) . to_term ( env) ) ?. decode ( ) ?;
82
+ let iframe_srcdoc: bool =
83
+ term. map_get ( atoms:: iframe_srcdoc ( ) . to_term ( env) ) ?. decode ( ) ?;
84
+ let drop_doctype: bool =
85
+ term. map_get ( atoms:: drop_doctype ( ) . to_term ( env) ) ?. decode ( ) ?;
86
+
87
+ Ok ( ParseOpts {
88
+ tokenizer : TokenizerOpts {
89
+ exact_errors : errors == ErrorLevel :: All ,
90
+ discard_bom : discard_bom,
91
+ profile : false ,
92
+ initial_state : None ,
93
+ last_start_tag_name : None ,
94
+ } ,
95
+ tree_builder : TreeBuilderOpts {
96
+ exact_errors : errors == ErrorLevel :: All ,
97
+ scripting_enabled : scripting_enabled,
98
+ iframe_srcdoc : iframe_srcdoc,
99
+ drop_doctype : drop_doctype,
100
+ ignore_missing_rules : false ,
101
+ quirks_mode : QuirksMode :: NoQuirks ,
102
+ } ,
103
+ } )
34
104
}
35
105
}
36
106
@@ -113,8 +183,10 @@ fn parse_async<'a>(env: NifEnv<'a>, args: &Vec<NifTerm<'a>>) -> NifResult<NifTer
113
183
114
184
let return_pid = env. pid ( ) ;
115
185
186
+ //let config = term_to_configs(args[1]);
187
+
116
188
POOL . spawn ( move || {
117
- owned_env. send ( return_pid, |inner_env| {
189
+ owned_env. send_and_clear ( & return_pid, |inner_env| {
118
190
// This should not really be done in user code. We (Rustler project)
119
191
// need to find a better abstraction that eliminates this.
120
192
match panic:: catch_unwind ( || {
0 commit comments