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
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
use std::borrow::Borrow;
use std::collections::BTreeMap;
use std::fmt::Display;
use std::io::{self, Write};
use std::string::ToString;

use crate::{functions::*, html_escape, MapToJavaScriptHTML};

impl<K: 'static + Display + Ord, V: 'static + Display> MapToJavaScriptHTML<K> for BTreeMap<K, V> {
    fn to_javascript_html_to_vec<'a, S: Display>(
        &self,
        variable_name: S,
        output: &'a mut Vec<u8>,
    ) -> &'a [u8] {
        let variable_name = variable_name.to_string();

        let current_length = output.len();

        output.reserve((variable_name.len() + 11) * self.len());

        if is_number::<K>() {
            if is_number::<V>() {
                for (key, value) in self {
                    output.extend_from_slice(variable_name.as_bytes());
                    output.write_fmt(format_args!("[{}]={};", key, value)).unwrap();
                }
            } else {
                for (key, value) in self {
                    output.extend_from_slice(variable_name.as_bytes());
                    output.write_fmt(format_args!("[{}]='", key)).unwrap();
                    html_escape::encode_script_single_quoted_text_to_vec(value.to_string(), output);
                    output.extend_from_slice(b"';");
                }
            }
        } else if is_number::<V>() {
            for (key, value) in self {
                output.extend_from_slice(variable_name.as_bytes());
                output.extend_from_slice(b"['");
                html_escape::encode_script_single_quoted_text_to_vec(key.to_string(), output);
                output.extend_from_slice(b"']=");
                output.write_fmt(format_args!("{};", value)).unwrap();
            }
        } else {
            for (key, value) in self {
                output.extend_from_slice(variable_name.as_bytes());
                output.extend_from_slice(b"['");
                html_escape::encode_script_single_quoted_text_to_vec(key.to_string(), output);
                output.extend_from_slice(b"']='");
                html_escape::encode_script_single_quoted_text_to_vec(value.to_string(), output);
                output.extend_from_slice(b"';");
            }
        }

        &output[current_length..]
    }

    fn to_javascript_html_to_writer<S: Display, W: Write>(
        &self,
        variable_name: S,
        output: &mut W,
    ) -> Result<(), io::Error> {
        let variable_name = variable_name.to_string();

        if is_number::<K>() {
            if is_number::<V>() {
                for (key, value) in self {
                    output.write_all(variable_name.as_bytes())?;
                    output.write_fmt(format_args!("[{}]={};", key, value))?;
                }
            } else {
                for (key, value) in self {
                    output.write_all(variable_name.as_bytes())?;
                    output.write_fmt(format_args!("[{}]='", key))?;
                    html_escape::encode_script_single_quoted_text_to_writer(
                        value.to_string(),
                        output,
                    )?;
                    output.write_all(b"';")?;
                }
            }
        } else if is_number::<V>() {
            for (key, value) in self {
                output.write_all(variable_name.as_bytes())?;
                output.write_all(b"['")?;
                html_escape::encode_script_single_quoted_text_to_writer(key.to_string(), output)?;
                output.write_all(b"']=")?;
                output.write_fmt(format_args!("{};", value))?;
            }
        } else {
            for (key, value) in self {
                output.write_all(variable_name.as_bytes())?;
                output.write_all(b"['")?;
                html_escape::encode_script_single_quoted_text_to_writer(key.to_string(), output)?;
                output.write_all(b"']='")?;
                html_escape::encode_script_single_quoted_text_to_writer(value.to_string(), output)?;
                output.write_all(b"';")?;
            }
        }

        Ok(())
    }

    #[inline]
    fn to_javascript_html_with_keys_to_vec<'a, S: Display, KS: ?Sized + Display + Ord>(
        &self,
        variable_name: S,
        keys: &[&KS],
        output: &'a mut Vec<u8>,
    ) -> &'a [u8]
    where
        K: Borrow<KS>, {
        let variable_name = variable_name.to_string();

        let current_length = output.len();

        output.reserve((variable_name.len() + 11) * self.len());

        if is_number::<K>() {
            if is_number::<V>() {
                for key in keys.iter() {
                    output.extend_from_slice(variable_name.as_bytes());
                    match self.get(key) {
                        Some(value) => {
                            output.write_fmt(format_args!("[{}]={};", key, value)).unwrap();
                        }
                        None => {
                            output.write_fmt(format_args!("[{}]=undefined;", key)).unwrap();
                        }
                    }
                }
            } else {
                for key in keys.iter() {
                    output.extend_from_slice(variable_name.as_bytes());
                    output.write_fmt(format_args!("[{}]=", key)).unwrap();
                    match self.get(key) {
                        Some(value) => {
                            output.push(b'\'');
                            html_escape::encode_script_single_quoted_text_to_vec(
                                value.to_string(),
                                output,
                            );
                            output.extend_from_slice(b"';");
                        }
                        None => {
                            output.extend_from_slice(b"undefined;");
                        }
                    }
                }
            }
        } else if is_number::<V>() {
            for key in keys.iter() {
                output.extend_from_slice(variable_name.as_bytes());
                output.extend_from_slice(b"['");
                html_escape::encode_script_single_quoted_text_to_vec(key.to_string(), output);
                output.extend_from_slice(b"']=");
                match self.get(key) {
                    Some(value) => {
                        output.write_fmt(format_args!("{};", value)).unwrap();
                    }
                    None => {
                        output.extend_from_slice(b"undefined;");
                    }
                }
            }
        } else {
            for key in keys.iter() {
                output.extend_from_slice(variable_name.as_bytes());
                output.extend_from_slice(b"['");
                html_escape::encode_script_single_quoted_text_to_vec(key.to_string(), output);
                output.extend_from_slice(b"']=");
                match self.get(key) {
                    Some(value) => {
                        output.push(b'\'');
                        html_escape::encode_script_single_quoted_text_to_vec(
                            value.to_string(),
                            output,
                        );
                        output.extend_from_slice(b"';");
                    }
                    None => {
                        output.extend_from_slice(b"undefined;");
                    }
                }
            }
        }

        unsafe { output.get_unchecked(current_length..) }
    }

    fn to_javascript_html_with_keys_to_writer<S: Display, W: Write, KS: ?Sized + Display + Ord>(
        &self,
        variable_name: S,
        keys: &[&KS],
        output: &mut W,
    ) -> Result<(), io::Error>
    where
        K: Borrow<KS>, {
        let variable_name = variable_name.to_string();

        if is_number::<K>() {
            if is_number::<V>() {
                for key in keys.iter() {
                    output.write_all(variable_name.as_bytes())?;
                    match self.get(key) {
                        Some(value) => {
                            output.write_fmt(format_args!("[{}]={};", key, value))?;
                        }
                        None => {
                            output.write_fmt(format_args!("[{}]=undefined;", key))?;
                        }
                    }
                }
            } else {
                for key in keys.iter() {
                    output.write_all(variable_name.as_bytes())?;
                    output.write_fmt(format_args!("[{}]=", key))?;
                    match self.get(key) {
                        Some(value) => {
                            output.write_all(b"'")?;
                            html_escape::encode_script_single_quoted_text_to_writer(
                                value.to_string(),
                                output,
                            )?;
                            output.write_all(b"';")?;
                        }
                        None => {
                            output.write_all(b"undefined;")?;
                        }
                    }
                }
            }
        } else if is_number::<V>() {
            for key in keys.iter() {
                output.write_all(variable_name.as_bytes())?;
                output.write_all(b"['")?;
                html_escape::encode_script_single_quoted_text_to_writer(key.to_string(), output)?;
                output.write_all(b"']=")?;
                match self.get(key) {
                    Some(value) => {
                        output.write_fmt(format_args!("{};", value))?;
                    }
                    None => {
                        output.write_all(b"undefined;")?;
                    }
                }
            }
        } else {
            for key in keys.iter() {
                output.write_all(variable_name.as_bytes())?;
                output.write_all(b"['")?;
                html_escape::encode_script_single_quoted_text_to_writer(key.to_string(), output)?;
                output.write_all(b"']=")?;
                match self.get(key) {
                    Some(value) => {
                        output.write_all(b"'")?;
                        html_escape::encode_script_single_quoted_text_to_writer(
                            value.to_string(),
                            output,
                        )?;
                        output.write_all(b"';")?;
                    }
                    None => {
                        output.write_all(b"undefined;")?;
                    }
                }
            }
        }

        Ok(())
    }
}