1 /++
2 Information about classes in a Godot-D project.
3 
4 These structs only store the info to be used by Godot-D. Use the class-finder
5 subpackage to actually obtain the info by parsing D files.
6 
7 TODO: replace temporary CSV serialization with proper JSON.
8 +/
9 module godot.util.classes;
10 
11 import std.string;
12 
13 import std.algorithm : map;
14 import std.array : join;
15 import std.range;
16 import std.conv : text;
17 import std.meta;
18 
19 /// Information about what classes were found in a D source file.
20 struct FileInfo {
21     string name; /// filename relative to the source directory
22     string hash; /// hash of the file, to avoid re-parsing files that haven't changed
23     string moduleName;
24     string mainClass; /// the class with the same name as the module, if it exists
25     bool hasEntryPoint = false; /// the GodotNativeLibrary mixin is in this file
26     string[] classes; /// all classes in the file
27 
28     string toCsv() const {
29         string ret = only(name, hash, moduleName, mainClass).join(",");
30         ret ~= ",";
31         ret ~= hasEntryPoint.text;
32         foreach (c; classes) {
33             ret ~= ",";
34             ret ~= c;
35         }
36         return ret;
37     }
38 
39     static FileInfo fromCsv(string csv) {
40         FileInfo ret;
41         auto s = csv.split(',');
42         static foreach (v; AliasSeq!("name", "hash", "moduleName", "mainClass")) {
43             mixin("ret." ~ v ~ " = s.front;");
44             s.popFront();
45         }
46         if (s.front == "true")
47             ret.hasEntryPoint = true;
48         s.popFront();
49         foreach (c; s) {
50             ret.classes ~= c;
51         }
52         return ret;
53     }
54 }
55 
56 /// 
57 struct ProjectInfo {
58     FileInfo[] files;
59 
60     /// the project has a GodotNativeLibrary mixin in one of its files
61     bool hasEntryPoint() const {
62         import std.algorithm.searching : any;
63 
64         return files.any!(f => f.hasEntryPoint);
65     }
66 
67     const(string)[] allClasses() const {
68         return files.map!(f => f.classes).join();
69     }
70 
71     string toCsv() const {
72         return files.map!(f => f.toCsv).join("\n");
73     }
74 
75     static ProjectInfo fromCsv(string csv) {
76         ProjectInfo ret;
77         foreach (l; csv.splitLines) {
78             ret.files ~= FileInfo.fromCsv(l);
79         }
80         return ret;
81     }
82 }