neutralts/
constants.rs

1use std::collections::HashMap;
2use lazy_static::lazy_static;
3use std::env;
4
5/// neutralts version
6pub const VERSION: &str = env!("CARGO_PKG_VERSION");
7
8
9///  Bif delimiters
10///
11/// ```text
12///   .------------------------------> BIF_OPEN = { + BIF_DELIM
13///   |.-----------------------------> BIF_DELIM
14///   ||.----------------------------> BIF_MOD_... (Modifiers)
15///   |||       .--------------------> BIF_NAME
16///   |||       |    .---------------> BIF_ARRAY
17///   |||       |    ||    .---------> BIF_CODE
18///   |||       |    ||    ||      .-> BIF_CLOSE = BIF_DELIM + }
19///   |||       |    ||    ||      |
20///   vvv       v    vv    vv      v
21///   {:!snippet; var->key >> ... :}
22/// ```
23pub const BIF_DELIM: &str = ":";
24
25///  Bif delimiters
26///
27/// ```text
28///   .------------------------------> BIF_OPEN = { + BIF_DELIM
29///   |.-----------------------------> BIF_DELIM
30///   ||.----------------------------> BIF_MOD_... (Modifiers)
31///   |||       .--------------------> BIF_NAME
32///   |||       |    .---------------> BIF_ARRAY
33///   |||       |    ||    .---------> BIF_CODE
34///   |||       |    ||    ||      .-> BIF_CLOSE = BIF_DELIM + }
35///   |||       |    ||    ||      |
36///   vvv       v    vv    vv      v
37///   {:!snippet; var->key >> ... :}
38/// ```
39pub const BIF_OPEN: &str = "{:";
40
41///  Bif delimiters
42///
43/// ```text
44///   .------------------------------> BIF_OPEN = { + BIF_DELIM
45///   |.-----------------------------> BIF_DELIM
46///   ||.----------------------------> BIF_MOD_... (Modifiers)
47///   |||       .--------------------> BIF_NAME
48///   |||       |    .---------------> BIF_ARRAY
49///   |||       |    ||    .---------> BIF_CODE
50///   |||       |    ||    ||      .-> BIF_CLOSE = BIF_DELIM + }
51///   |||       |    ||    ||      |
52///   vvv       v    vv    vv      v
53///   {:!snippet; var->key >> ... :}
54/// ```
55pub const BIF_CLOSE: &str = ":}";
56
57///  Bif delimiters
58///
59/// ```text
60///   .------------------------------> BIF_OPEN = { + BIF_DELIM
61///   |.-----------------------------> BIF_DELIM
62///   ||.----------------------------> BIF_MOD_... (Modifiers)
63///   |||       .--------------------> BIF_NAME
64///   |||       |    .---------------> BIF_ARRAY
65///   |||       |    ||    .---------> BIF_CODE
66///   |||       |    ||    ||      .-> BIF_CLOSE = BIF_DELIM + }
67///   |||       |    ||    ||      |
68///   vvv       v    vv    vv      v
69///   {:!snippet; var->key >> ... :}
70/// ```
71pub const BIF_NAME: &str = ";";
72
73///  Bif delimiters
74///
75/// ```text
76///   .------------------------------> BIF_OPEN = { + BIF_DELIM
77///   |.-----------------------------> BIF_DELIM
78///   ||.----------------------------> BIF_MOD_... (Modifiers)
79///   |||       .--------------------> BIF_NAME
80///   |||       |    .---------------> BIF_ARRAY
81///   |||       |    ||    .---------> BIF_CODE
82///   |||       |    ||    ||      .-> BIF_CLOSE = BIF_DELIM + }
83///   |||       |    ||    ||      |
84///   vvv       v    vv    vv      v
85///   {:!snippet; var->key >> ... :}
86/// ```
87pub const BIF_CODE: &str = ">>";
88
89///  Bif delimiters
90///
91/// ```text
92///   .------------------------------> BIF_OPEN = { + BIF_DELIM
93///   |.-----------------------------> BIF_DELIM
94///   ||.----------------------------> BIF_MOD_... (Modifiers)
95///   |||       .--------------------> BIF_NAME
96///   |||       |    .---------------> BIF_ARRAY
97///   |||       |    ||    .---------> BIF_CODE
98///   |||       |    ||    ||      .-> BIF_CLOSE = BIF_DELIM + }
99///   |||       |    ||    ||      |
100///   vvv       v    vv    vv      v
101///   {:!snippet; var->key >> ... :}
102/// ```
103pub const BIF_ARRAY: &str = "->";
104
105///  Bif comment
106///
107/// ```text
108///      .---> BIF_COMMENT
109///     |
110///     v
111///   {:* commnet *:}
112/// ```
113pub const BIF_COMMENT: &str = "*";
114
115///  Bif comment open
116///
117/// ```text
118///   .---> BIF_COMMENT_OPEN
119///   |||
120///   vvv
121///   {:* commnet *:}
122/// ```
123pub const BIF_COMMENT_OPEN: &str = "{:*";
124
125///  Bif comment close
126///
127/// ```text
128///               .---> BIF_COMMENT_CLOSE
129///               |||
130///               vvv
131///   {:* commnet *:}
132/// ```
133pub const BIF_COMMENT_CLOSE: &str = "*:}";
134
135/// modifier filter
136pub const BIF_MOD_FILTER: &str = "&";
137
138/// modifier not
139pub const BIF_MOD_NEGATE: &str = "!";
140
141/// modifier upline
142pub const BIF_MOD_UPLINE: &str = "^";
143
144/// modifier scope
145pub const BIF_MOD_SCOPE: &str = "+";
146
147/// Identify bif var as it has no name
148pub const BIF_VAR: &str = "{:;";
149
150/// delim as bytes
151pub const BIF_DELIM_B: &[u8] = BIF_DELIM.as_bytes();
152
153/// BIF_OPEN as bytes
154pub const BIF_OPEN_B: &[u8] = BIF_OPEN.as_bytes();
155
156/// BIF_OPEN 0 as bytes
157pub const BIF_OPEN0: u8 = BIF_OPEN.as_bytes()[0];
158
159/// BIF_OPEN 1 as bytes
160pub const BIF_OPEN1: u8 = BIF_OPEN.as_bytes()[1];
161
162/// BIF_CLOSE as bytes
163pub const BIF_CLOSE_B: &[u8] = BIF_CLOSE.as_bytes();
164
165/// BIF_CLOSE 0 as bytes
166pub const BIF_CLOSE0: u8 = BIF_CLOSE.as_bytes()[0];
167
168/// BIF_CLOSE 1 as bytes
169pub const BIF_CLOSE1: u8 = BIF_CLOSE.as_bytes()[1];
170
171/// BIF_CODE as bytes
172pub const BIF_CODE_B: &[u8] = BIF_CODE.as_bytes();
173
174/// BIF_COMMENT as bytes
175pub const BIF_COMMENT_B: u8 = BIF_COMMENT.as_bytes()[0];
176
177/// BIF_COMMENT_OPEN as bytes
178pub const BIF_COMMENT_OPEN_B: &[u8] = BIF_COMMENT_OPEN.as_bytes();
179
180/// BIF_COMMENT_CLOSE as bytes
181pub const BIF_COMMENT_CLOSE_B: &[u8] = BIF_COMMENT_CLOSE.as_bytes();
182
183/// replacement for BIF_OPEN sanitation
184pub const BIF_SANITIZE_OPEN: &str = "{:";
185
186/// replacement for BIF_CLOSE sanitation
187pub const BIF_SANITIZE_CLOSE: &str = ":}";
188
189/// html entity for {:;:}
190pub const UNPRINTABLE: &str = "�";
191
192/// html entity for null
193pub const NULL: &str = "�";
194
195/// empty
196pub const EMPTY: &str = "";
197
198/// Empty string could be different in different environments and could be an
199/// HTM entity. It is also used to make it clear that it is an empty string.
200pub const EMPTY_STRING: String = String::new();
201
202/// html entity for space
203pub const SPACE: &str = " ";
204
205/// html entity for crlf
206pub const CRLF: &str = "
";
207
208/// html entity for Backspace
209pub const BACKSPACE: &str = "&#9224";
210
211/// false
212pub const FALSE: bool = false;
213
214/// true
215pub const TRUE: bool = true;
216
217/// Identify bif allow
218pub const BIF_ALLOWED: [&str; 2] = ["{:allow;", "{:!allow;"];
219
220/// To detect the template files that may contain snippet
221pub const SNIPPETS_FILES: &str = "snippet";
222
223/// bif list
224pub const BIF_LIST: [&str; 36] = [
225    "",
226    "allow",
227    "array",
228    "bool",
229    "cache",
230    "coalesce",
231    "code",
232    "contains",
233    "count",
234    "data",
235    "date",
236    "declare",
237    "defined",
238    "each",
239    "else",
240    "eval",
241    "exit",
242    "fetch",
243    "filled",
244    "flg",
245    "for",
246    "hash",
247    "include",
248    "join",
249    "lang",
250    "locale",
251    "moveto",
252    "neutral",
253    "param",
254    "rand",
255    "redirect",
256    "replace",
257    "same",
258    "snippet",
259    "sum",
260    "trans",
261];
262
263/// bif alias list because some bifs have no name
264pub const BIF_ALIAS_LIST: [&str; 37] = [
265    "allow",
266    "array",
267    "bool",
268    "cache",
269    "coalesce",
270    "code",
271    "contains",
272    "count",
273    "data",
274    "date",
275    "declare",
276    "defined",
277    "each",
278    "else",
279    "eval",
280    "exit",
281    "fetch",
282    "filled",
283    "flg",
284    "for",
285    "hash",
286    "include",
287    "join",
288    "lang",
289    "locale",
290    "moveto",
291    "neutral",
292    "param",
293    "rand",
294    "redirect",
295    "replace",
296    "same",
297    "snippet",
298    "sum",
299    "trans",
300    "unprintable",
301    "var",
302];
303
304lazy_static! {
305    /// HTTP status codes
306    pub static ref STATUS_CODES: HashMap<&'static str, &'static str> = {
307        let mut m = HashMap::new();
308        m.insert("100", "Continue");
309        m.insert("101", "Switching Protocols");
310        m.insert("103", "Early Hints");
311        m.insert("200", "OK");
312        m.insert("201", "Created");
313        m.insert("202", "Accepted");
314        m.insert("203", "Non-Authoritative Information");
315        m.insert("204", "No Content");
316        m.insert("205", "Reset Content");
317        m.insert("206", "Partial Content");
318        m.insert("208", "Already Reported");
319        m.insert("226", "IM Used");
320        m.insert("300", "Multiple Choices");
321        m.insert("301", "Moved Permanently");
322        m.insert("302", "Found");
323        m.insert("303", "See Other");
324        m.insert("304", "Not Modified");
325        m.insert("305", "Use Proxy");
326        m.insert("306", "Switch Proxy"); // old http version
327        m.insert("307", "Temporary Redirect");
328        m.insert("308", "Permanent Redirect");
329        m.insert("400", "Bad Request");
330        m.insert("401", "Unauthorized");
331        m.insert("402", "Payment Required");
332        m.insert("403", "Forbidden");
333        m.insert("404", "Not Found");
334        m.insert("405", "Method Not Allowed");
335        m.insert("406", "Not Acceptable");
336        m.insert("407", "Proxy Authentication Required");
337        m.insert("408", "Request Time-out");
338        m.insert("409", "Conflict");
339        m.insert("410", "Gone");
340        m.insert("411", "Length Required");
341        m.insert("412", "Precondition Failed");
342        m.insert("413", "Payload Too Large");
343        m.insert("414", "URI Too Long");
344        m.insert("415", "Unsupported Media Type");
345        m.insert("416", "Range Not Satisfiable");
346        m.insert("417", "Expectation Failed");
347        m.insert("421", "Misdirected Request");
348        m.insert("422", "Unprocessable Entity");
349        m.insert("423", "Locked");
350        m.insert("424", "Failed Dependency");
351        m.insert("425", "Too Early");
352        m.insert("426", "Upgrade Required");
353        m.insert("428", "Precondition Required");
354        m.insert("429", "Too Many Requests");
355        m.insert("431", "Request Header Fields Too Large");
356        m.insert("451", "Unavailable For Legal Reasons");
357        m.insert("500", "Internal Server Error");
358        m.insert("501", "Not Implemented");
359        m.insert("502", "Bad Gateway");
360        m.insert("503", "Service Unavailable");
361        m.insert("504", "Gateway Time-out");
362        m.insert("505", "HTTP Version Not Supported");
363        m.insert("506", "Variant Also Negotiates (Experimental)");
364        m.insert("510", "Not Extended");
365        m.insert("511", "Network Authentication Required");
366
367        m
368    };
369}
370
371/// JavaScript script reloads the current top page, used in {:redirect;
372pub const REDIR_JS_RELOAD_TOP: &str = "<!DOCTYPE html><script>top.location.href=self.location.href.split('#')[0];</script>";
373
374/// JavaScript script reloads the current, used in {:redirect;
375pub const REDIR_JS_RELOAD_SELF: &str = "<!DOCTYPE html><script>self.location.href=self.location.href.split('#')[0]</script>";
376
377/// JavaScript script that redirects to a new URL in the top page, used in {:redirect;
378/// The placeholder '{}' should be replaced with the destination url.
379pub const REDIR_JS_REDIRECT_TOP: &str = "<!DOCTYPE html><script>top.location.href='{}';</script>";
380
381/// JavaScript script that redirects to a new URL in the self page, used in {:redirect;
382/// The placeholder '{}' should be replaced with the destination url.
383pub const REDIR_JS_REDIRECT_SELF: &str = "<!DOCTYPE html><script>self.location.href='{}';</script>";
384
385lazy_static! {
386    /// JavaScript for {:fetch; ... :}
387    pub static ref NEUTRAL_JS: String = r#"<script>{
388        const d=document;
389        let sl='...';
390        let sd=250;
391        let st=30000;
392        let se=' Form ERROR! ';
393        let sed=3500;
394        "undefined"!=typeof neutral_submit_loading&&(sl=neutral_submit_loading);
395        "undefined"!=typeof neutral_submit_delay&&(sd=neutral_submit_delay);
396        "undefined"!=typeof neutral_submit_timeout&&(st=neutral_submit_timeout);
397        "undefined"!=typeof neutral_submit_error&&(se=neutral_submit_error);
398        "undefined"!=typeof neutral_submit_error_delay&&(sed=neutral_submit_error_delay);
399
400        const o=new IntersectionObserver((e)=>{
401            e.forEach(e=>{
402                if(e.isIntersecting){
403                    o.unobserve(e.target);
404                    neutral_fetch(e.target,e.target.dataset.url,e.target.dataset.wrap);
405                }
406            });
407        });
408
409        function neutral_obs(){
410            d.querySelectorAll('.neutral-fetch-visible').forEach((e)=>{
411                e.classList.remove('neutral-fetch-visible');
412                o.observe(e);
413            });
414        }
415
416        function neutral_fetch(e,u,w){
417            let h=e;if(w){h=d.getElementById(w)}
418            fetch(u,{headers:{'requested-with-ajax':'fetch'}})
419            .then(response=>response.text())
420            .then(html=>{
421                h.innerHTML=html;
422                h.outerHTML=html;
423                window.dispatchEvent(new CustomEvent('neutralFetchCompleted',{detail:{element:h,url:u}}));
424            })
425            .catch(error=>{
426                h.innerHTML=se;
427                window.dispatchEvent(new CustomEvent('neutralFetchError',{detail:{element:h,url:u}}));
428            });
429        }
430
431        function neutral_fetch_form(f,u,w){
432            const subs = f.querySelectorAll('[type=submit]');
433            subs.forEach((e)=>{
434                e.disabled=true;
435                e.dataset['restsubs']=e.innerHTML;
436                e.innerHTML=e.innerHTML + ' ' + sl;
437            });
438            let h=f;if(w){h = d.getElementById(w)}
439            let dt=new FormData(f);
440            let has_file=false;
441            for(let i=0;i<f.elements.length;i++){
442                value=f.elements[i].value;
443                if(f.elements[i].name===""){
444                    continue;
445                }
446                if(f.elements[i].type=="file"){
447                    has_file=true;
448                    continue;
449                }
450                if(f.elements[i].name.indexOf('[]')>=0){
451                    continue;
452                }
453                if(f.elements[i].type=="checkbox" || f.elements[i].type=="radio"){
454                    if(!f.elements[i].checked){
455                        continue;
456                    }
457                }
458                dt.append(f.elements[i].name,value);
459            }
460            if(!has_file){dt=new URLSearchParams(new FormData(f))}
461            setTimeout(()=>{
462                fetch(u,{
463                    signal:AbortSignal.timeout(st),
464                    method:'POST',
465                    headers:{'requested-with-ajax':'fetch'},
466                    body:dt,
467                })
468                .then(response=>response.text())
469                .then(html=>{
470                    h.innerHTML=html;
471                    h.outerHTML=html;
472                    window.dispatchEvent(new CustomEvent('neutralFetchCompleted',{detail:{element:h,url:u}}));
473                })
474                .catch(error=>{
475                    window.dispatchEvent(new CustomEvent('neutralFetchError',{detail:{element:h,url:u}}));
476                    subs.forEach((e)=>{e.disabled=true;e.innerHTML=se;});
477                    setTimeout(()=>{
478                        subs.forEach((e)=>{e.disabled=false;e.innerHTML=e.dataset['restsubs']});
479                    },sed);
480                });
481            },sd);
482        }
483
484        function neutral_fev(){
485            d.querySelectorAll('.neutral-fetch-form').forEach((e)=>{
486                e.classList.remove('neutral-fetch-form');
487                function handleSubmit(ev){
488                    ev.preventDefault();
489                    neutral_fetch_form(e,e.getAttribute('action'),e.dataset.wrap);
490                }
491                e.addEventListener('submit',handleSubmit);
492            });
493
494            d.querySelectorAll('.neutral-fetch-auto').forEach((e)=>{
495                e.classList.remove('neutral-fetch-auto');
496                neutral_fetch(e,e.dataset.url,e.dataset.wrap);
497            });
498
499            d.querySelectorAll('.neutral-fetch-click').forEach((e)=>{
500                e.classList.remove('neutral-fetch-click');
501                function handleClick(){
502                    neutral_fetch(e,e.dataset.url,e.dataset.wrap);
503                }
504                e.addEventListener('click',handleClick);
505            });
506            neutral_obs();
507        }
508
509        d.addEventListener('DOMContentLoaded',()=>{
510            neutral_fev();
511        });
512        window.addEventListener('neutralFetchCompleted',()=>{
513            neutral_fev();
514        });
515        window.addEventListener('neutralFetchError',()=>{
516            neutral_fev();
517        });
518    }</script>"#.replace("\n", "").replace("  ", "");
519}
520
521/// HTML container form for {:fetch; ... :}
522pub const DIV_FETCH_FORM: &str = r#"
523<form id="{id}" name="{name}" class="neutral-fetch-form {class}" method="POST" action="{endpoint}" data-wrap="{wrap}">
524    {body}
525</form>
526"#;
527
528/// HTML container none for {:fetch; ... :}
529pub const DIV_FETCH_NONE: &str = r#"
530<div id="{id}" class="neutral-fetch-none {class}" data-url="{endpoint}" data-wrap="{wrap}">
531    {body}
532</div>
533"#;
534
535/// HTML container auto for {:fetch; ... :}
536pub const DIV_FETCH_AUTO: &str = r#"
537<div id="{id}" class="neutral-fetch-auto {class}" data-url="{endpoint}" data-wrap="{wrap}">
538    {body}
539</div>
540"#;
541
542/// HTML container visible for {:fetch; ... :}
543pub const DIV_FETCH_VISIBLE: &str = r#"
544<div id="{id}" class="neutral-fetch-visible {class}" data-url="{endpoint}" data-wrap="{wrap}">
545    {body}
546</div>
547"#;
548
549/// HTML container click for {:fetch; ... :}
550pub const DIV_FETCH_CLICK: &str = r#"
551<div id="{id}" class="neutral-fetch-click {class}" data-url="{endpoint}" data-wrap="{wrap}">
552    {body}
553</div>
554"#;
555
556pub const DEFAULT_OBJ_ENGINE: &str = "python";
557pub const DEFAULT_OBJ_CALLBACK: &str = "main";