1 /*
2  *Copyright (C) 2018 Laurent Tréguier
3  *
4  *This file is part of DLS.
5  *
6  *DLS is free software: you can redistribute it and/or modify
7  *it under the terms of the GNU General Public License as published by
8  *the Free Software Foundation, either version 3 of the License, or
9  *(at your option) any later version.
10  *
11  *DLS is distributed in the hope that it will be useful,
12  *but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *GNU General Public License for more details.
15  *
16  *You should have received a copy of the GNU General Public License
17  *along with DLS.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 module dls.util.uri;
22 
23 class Uri
24 {
25     import dls.protocol.definitions : DocumentUri;
26     import std.regex : regex;
27 
28     private static enum _reg = regex(
29                 `(?:([\w-]+)://)?([\w.]+(?::\d+)?)?([^\?#]+)(?:\?([\w=&]+))?(?:#([\w-]+))?`);
30     private string _uri;
31     private string _scheme;
32     private string _authority;
33     private string _path;
34     private string _query;
35     private string _fragment;
36 
37     @property string path() const
38     {
39         return _path;
40     }
41 
42     this(DocumentUri uri)
43     {
44         import dls.util.path : normalized;
45         import std.conv : to;
46         import std.path : asNormalizedPath;
47         import std.regex : matchAll;
48         import std.uri : decodeComponent;
49         import std.utf : toUTF32;
50 
51         auto matches = matchAll(decodeComponent(uri.toUTF32()), _reg);
52 
53         //dfmt off
54         _uri        = uri;
55         _scheme     = matches.front[1];
56         _authority  = matches.front[2];
57         _path       = matches.front[3].asNormalizedPath().to!string.normalized;
58         _query      = matches.front[4];
59         _fragment   = matches.front[5];
60         //dfmt on
61     }
62 
63     override string toString() const
64     {
65         return _uri;
66     }
67 
68     static Uri fromPath(string path)
69     {
70         import std.algorithm : startsWith;
71         import std.format : format;
72         import std..string : tr;
73         import std.uri : encode;
74 
75         const uriPath = path.tr(`\`, `/`);
76         return new Uri(encode(format!"file://%s%s"(uriPath.startsWith('/') ? "" : "/", uriPath)));
77     }
78 
79     alias toString this;
80 }