1 module glued.utils;
2 
3 import std.algorithm;
4 import std.meta;
5 import std.range;
6 import std.traits;
7 import std..string;
8 
9 enum NewLineMode {
10     ALWAYS,
11     ON_CONTENT,
12     NEVER
13 }
14 
15 struct StringBuilder {
16     string result;
17     
18     void append(string line, NewLineMode newLine=NewLineMode.ON_CONTENT){
19         string suffix;
20         with (NewLineMode)
21         {
22             final switch (newLine)
23             {
24                 case ALWAYS: suffix = "\n"; break;
25                 case ON_CONTENT: suffix = line.strip.empty ? "" : "\n"; break;
26                 case NEVER: suffix = ""; break;
27             }
28         }
29         result ~= line ~ suffix;
30     }
31     
32     void removeEmptyLines(){
33         result = result.split("\n").filter!(x => !x.strip.empty).join("\n");
34     }
35 }
36 
37 template ofType(alias T) {
38     import std.traits;
39     static if (__traits(isTemplate, T)){
40         enum ofType(alias X) = (__traits(isSame, TemplateOf!(typeof(X)), T));
41     } else {
42         enum ofType(alias X) = (is(typeof(X) == T));
43     }
44 }
45 
46 template toType(alias T){
47     import std.traits;
48     static if (__traits(isTemplate, T)){
49         alias toType = TemplateOf!(typeof(T));
50     } else {
51         alias toType = typeof(T);
52     }
53     //todo message
54     static assert(isType!(toType)); //to fail on functions, methods, etc
55 }
56 
57 //fixme fugly name, its nothing to do with annotations, but I have no better idea now
58 template toAnnotableType(alias T){
59     alias toAnnotableType = AliasSeq!(NoDuplicates!(typeof(T), toType!(T)));
60 }
61 
62 enum isType(T) = (__traits(isTemplate, T) || is(T == class) || is(T == interface) || is(T == struct) || is(T == enum));
63 
64 template isRangeOf(R, T) {
65     enum isRangeOf = isInputRange!R && is(ReturnType!((R r) => r.front()) == T);
66 }
67 
68 //todo remove these from dejector, make dependency on utils and logging from there
69 enum isObjectType(T) = is(T == interface) || is(T == class);
70 enum isValueType(T) = is(T == struct) || is(T==enum);
71 
72 T nonNull(T)(T t) if (isObjectType!T) {
73     assert(t !is null); //todo exception
74     return t;
75 }
76 
77 bool isInstance(T, V)(V v) if (isObjectType!T && isObjectType!V){
78     T t = cast(T) v;
79     return t !is null;
80 }