1 module pastemyst.data;
2 
3 import std.typecons;
4 import std.uri;
5 import vibe.d;
6 import pastemyst.info;
7 
8 /++
9  + a struct representing a single language
10  +/
11 public struct Language
12 {
13     /++
14      + language name
15      +/
16     public string name;
17 
18     /++
19      + language mode (used for the online editor - codemirror)
20      +/
21     public string mode;
22 
23     /++
24      + all supported mimes
25      +/
26     public string[] mimes;
27 
28     /++
29      + all supported extensions
30      +/
31     public string[] ext;
32 
33     /++
34      + color of the language, not guaranteed that every language has it
35      + will be #ffffff if the language doesnt have a color
36      +/
37     @optional
38     public string color = "#ffffff";
39 }
40 
41 /++
42  + returns language information for a specific language, searched languages by name. if the language couldn't be found it returns null
43  +/
44 public Nullable!Language getLanguageByName(string name)
45 {
46     return getLanguage(DATA_LANGUAGE_BY_NAME, name);
47 }
48 
49 /++
50  + returns language information for a specific language, searched languages by extension. if the language couldn't be found it returns null
51  +
52  + dont include the . in the extension
53  +/
54 public Nullable!Language getLanguageByExtension(string extension)
55 {
56     return getLanguage(DATA_LANGUAGE_BY_EXT, extension);
57 }
58 
59 /++
60  + there are 2 endpoints that return languages, one by name and one by extension, they return same data
61  +
62  + this function just does a GET request on the provided endpoint with the provided value and returns a language
63  +/
64 private Nullable!Language getLanguage(string endpoint, string value)
65 {
66     Nullable!Language lang = Nullable!Language.init;
67 
68     requestHTTP(endpoint ~ encodeComponent(value),
69         (scope req)
70         {
71             req.method = HTTPMethod.GET;
72         },
73         (scope res)
74         {
75             if (res.statusCode != HTTPStatus.notFound)
76             {
77                 lang = nullable(deserializeJson!Language(res.bodyReader.readAllUTF8()));
78             }
79         }
80     );
81 
82     return lang;
83 }
84 
85 @("getting a language by name")
86 unittest
87 {
88     assert(getLanguageByName("non existing lang").isNull());
89     assert(getLanguageByName("asdasdasd").isNull());
90 
91     const lang = getLanguageByName("d").get();
92 
93     assert(lang.name == "D");
94 }
95 
96 @("getting a language by extension")
97 unittest
98 {
99     assert(getLanguageByExtension("brokey").isNull());
100 
101     const lang = getLanguageByExtension("d").get();
102 
103     assert(lang.name == "D");
104 }