1 /** 
2  * The custom text transformer that implements the gogga-stylised
3  * logging messages
4  */
5 module gogga.transform;
6 
7 import dlog;
8 import gogga.context;
9 import std.conv : to;
10 
11 /** 
12  * The gogga styles supported
13  */
14 public enum GoggaMode
15 {
16     TwoKTwenty3,
17     SIMPLE,
18     RUSTACEAN
19 }
20 
21 /** 
22  * The custom gogga text transformer
23  */
24 public class GoggaTransform : MessageTransform
25 {
26     /** 
27      * Current style
28      */
29     private GoggaMode mode;
30 
31     /** 
32      * Transforms the provided text
33      *
34      * Params:
35      *   text = text to transform
36      *   ctx = the context passed in
37      * Returns: a string of transformed text
38      */
39     public override string transform(string text, Context ctx)
40     {
41         /* The generated output string */
42         string finalOutput;
43 
44 
45         /* Get the GoggaContext */
46         GoggaContext gCtx = cast(GoggaContext)ctx;
47 
48         /* Extract the line information */
49         CompilationInfo compInfo = gCtx.getLineInfo();
50         string[] context = compInfo.toArray();
51 
52         /* Extract the Level */
53         Level level = gCtx.getLevel();
54 
55 
56         /** 
57          * Simple mode is just: `[<LEVEL>] <message>`
58          */
59         if(mode == GoggaMode.SIMPLE)
60         {
61             finalOutput = cast(string)debugColor("["~to!(string)(level)~"] ", level);
62 
63             finalOutput ~= text~"\n";
64         }
65         /** 
66          * TwoKTwenty3 is: `[<file>] (<module>:<lineNumber>) <message>`
67          */
68         else if(mode == GoggaMode.TwoKTwenty3)
69         {
70             /* Module information (and status debugColoring) */
71             string moduleInfo = cast(string)debugColor("["~context[1]~"]", level);
72             
73             /* Function and line number info */
74             string funcInfo = cast(string)(colorSrc("("~context[4]~":"~context[2]~")"));
75 
76             finalOutput =  moduleInfo~" "~funcInfo~" "~text~"\n";
77         }
78         /** 
79          * Rustacean mode is: `[<LEVEL>] (<filePath>/<functionName>:<lineNumber>) <message>`
80          */
81         else
82         {
83             finalOutput = cast(string)debugColor(to!(string)(level)~"\t", level);
84             finalOutput ~= cast(string)(colorSrc(context[1]~"/"~context[4]~":"~context[2]~"  "));
85             finalOutput ~= text~"\n";
86         }
87 
88         return finalOutput;
89     }
90 
91     /** 
92      * Set the gogga style
93      *
94      * Params:
95      *   mode = the GoggaMode to use
96      */
97     public void setMode(GoggaMode mode)
98     {
99         this.mode = mode;
100     }
101 }
102 
103 /** 
104  * Colorise the text provided accoridng to the level and then
105  * reset the colors at the end
106  *
107  * Params:
108  *   text = the text to colorise
109  *   level = the color to use
110  * Returns: the byte sequence of characters and controls
111  */
112 private byte[] debugColor(string text, Level level)
113 {
114     /* The generated message */
115     byte[] messageBytes;
116 
117     /* If INFO, set green */
118     if(level == Level.INFO)
119     {
120         messageBytes = cast(byte[])[27, '[','3','2','m'];
121     }
122     /* If WARNING, set warning */
123     else if(level == Level.WARN)
124     {
125         messageBytes = cast(byte[])[27, '[','3','5','m']; /* TODO: FInd yllow */
126     }
127     /* If ERROR, set error */
128     else if(level == Level.ERROR)
129     {
130         messageBytes = cast(byte[])[27, '[','3','1','m'];
131     }
132 
133     /* Add the message */
134     messageBytes ~= cast(byte[])text;
135 
136     /* Switch back debugColor */
137     messageBytes ~= cast(byte[])[27, '[', '3', '9', 'm'];
138 
139     /* Reset coloring */
140     messageBytes ~= [27, '[', 'm'];
141 
142     return messageBytes;
143 }
144 
145 /** 
146  * Colors the provided text in a gray fashion and then
147  * resets back to normal
148  *
149  * Params:
150  *   text = the text to gray color
151  * Returns: the byte sequence of characters and controls
152  */
153 private byte[] colorSrc(string text)
154 {
155     /* The generated message */
156     byte[] messageBytes;
157 
158     /* Reset coloring */
159     messageBytes ~= [27, '[', 'm'];
160 
161     /* Color gray */
162     messageBytes ~= [27, '[', '3', '9', ';', '2', 'm'];
163 
164     /* Append the message */
165     messageBytes ~= text;
166 
167     /* Reset coloring */
168     messageBytes ~= [27, '[', 'm'];
169 
170     return messageBytes;
171 }