1 module dls.util.uri;
2 
3 class Uri
4 {
5     import dls.protocol.definitions : DocumentUri;
6     import dls.util.path : normalized;
7     import std.regex : regex;
8 
9     private static enum _reg = regex(
10                 `(?:([\w-]+)://)?([\w.]+(?::\d+)?)?([^\?#]+)(?:\?([\w=&]+))?(?:#([\w-]+))?`);
11     private string _uri;
12     private string _scheme;
13     private string _authority;
14     private string _path;
15     private string _query;
16     private string _fragment;
17 
18     @property string path() const
19     {
20         return _path;
21     }
22 
23     this(DocumentUri uri)
24     {
25         import std.conv : to;
26         import std.path : asNormalizedPath;
27         import std.regex : matchAll;
28         import std.uri : decodeComponent;
29         import std.utf : toUTF32;
30 
31         auto matches = matchAll(decodeComponent(uri.toUTF32()), _reg);
32 
33         //dfmt off
34         _uri        = uri;
35         _scheme     = matches.front[1];
36         _authority  = matches.front[2];
37         _path       = matches.front[3].asNormalizedPath().to!string.normalized;
38         _query      = matches.front[4];
39         _fragment   = matches.front[5];
40         //dfmt on
41     }
42 
43     override string toString() const
44     {
45         return _uri;
46     }
47 
48     static string getPath(DocumentUri uri)
49     {
50         return new Uri(uri).path;
51     }
52 
53     static Uri fromPath(string path)
54     {
55         import std.algorithm : startsWith;
56         import std.format : format;
57         import std.string : tr;
58         import std.uri : encode;
59 
60         const uriPath = path.tr(`\`, `/`);
61         return new Uri(encode(format!"file://%s%s"(uriPath.startsWith('/') ? "" : "/", uriPath)));
62     }
63 
64     alias toString this;
65 }