1 module orelang.operator.UriOperators;
2 import orelang.operator.IOperator,
3        orelang.Engine,
4        orelang.Value;
5 import std.regex,
6        std.uri : encodeComponentUnsafe = encodeComponent;
7 
8 static string encodeComponent(string s) {
9   char hexChar(ubyte c) {
10     assert(c >= 0 && c <= 15);
11     if (c < 10)
12       return cast(char)('0' + c);
13     else
14       return cast(char)('A' + c - 10);
15   }
16 
17   enum InvalidChar = ctRegex!`[!\*'\(\)]`;
18 
19   return s.encodeComponentUnsafe.replaceAll!((s) {
20         char c = s.hit[0];
21         char[3] encoded;
22         encoded[0] = '%';
23         encoded[1] = hexChar((c >> 4) & 0xF);
24         encoded[2] = hexChar(c & 0xF);
25         return encoded[].idup;
26       })(InvalidChar);
27 }
28 
29 class UrlEncodeComponentOperator : IOperator {
30   /**
31    * call
32    */
33 
34    Value call(Engine engine, Value[] args) {
35      string s = engine.eval(args[0]).getString;
36 
37      return new Value(encodeComponent(s));
38    }
39 }