1 /*
2  * hunt-console eases the creation of beautiful and testable command line interfaces.
3  *
4  * Copyright (C) 2018-2019, HuntLabs
5  *
6  * Website: https://www.huntlabs.net
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11  
12 module hunt.console.output.AbstractOutput;
13 
14 import hunt.console.error.InvalidArgumentException;
15 import hunt.console.formatter.DefaultOutputFormatter;
16 import hunt.console.formatter.OutputFormatter;
17 import hunt.console.output.Output;
18 import hunt.console.output.Verbosity;
19 import hunt.console.output.OutputType;
20 
21 import std.string;
22 /**
23  * Base class for output classes.
24  *
25  * There are five levels of verbosity:
26  *
27  *  * normal: no option passed (normal output)
28  *  * verbose: -v (more output)
29  *  * very verbose: -vv (highly extended output)
30  *  * debug: -vvv (all debug output)
31  *  * quiet: -q (no output)
32  */
33 public abstract class AbstractOutput : Output
34 {
35     private Verbosity verbosity;
36     private OutputFormatter formatter;
37 
38     public this()
39     {
40         this(Verbosity.NORMAL);
41     }
42 
43     public this(Verbosity verbosity)
44     {
45         this(verbosity, true);
46     }
47 
48     public this(Verbosity verbosity, bool decorated)
49     {
50         this(verbosity, decorated, new DefaultOutputFormatter());
51     }
52 
53     public this(Verbosity verbosity, bool decorated, OutputFormatter formatter)
54     {
55         this.verbosity = verbosity;
56         this.formatter = formatter;
57         this.formatter.setDecorated(decorated);
58     }
59 
60     /* override */ public void setFormatter(OutputFormatter formatter)
61     {
62         this.formatter = formatter;
63     }
64 
65     /* override */ public OutputFormatter getFormatter()
66     {
67         return formatter;
68     }
69 
70     override public void setDecorated(bool decorated)
71     {
72         formatter.setDecorated(decorated);
73     }
74 
75     override public bool isDecorated()
76     {
77         return formatter.isDecorated();
78     }
79 
80     override public void setVerbosity(Verbosity verbosity)
81     {
82         this.verbosity = verbosity;
83     }
84 
85     override public Verbosity getVerbosity()
86     {
87         return verbosity;
88     }
89 
90     public bool isQuiet()
91     {
92         return verbosity == Verbosity.QUIET;
93     }
94 
95     public bool isVerbose()
96     {
97         return cast(int)verbosity >= cast(int)(Verbosity.VERBOSE);
98     }
99 
100     public bool isVeryVerbose()
101     {
102         return cast(int)(verbosity) >= cast(int)(Verbosity.VERY_VERBOSE);
103     }
104 
105     public bool isDebug()
106     {
107         return cast(int)(verbosity) >= cast(int)(Verbosity.DEBUG);
108     }
109 
110     override public void write(string message)
111     {
112         write(message, false);
113     }
114 
115     override public void write(string message, bool newline)
116     {
117         write(message, newline, OutputType.NORMAL);
118     }
119 
120     override public void write(string message, bool newline, OutputType type)
121     {
122         if (isQuiet()) {
123             return;
124         }
125 
126         switch (type) with(OutputType){
127             case NORMAL:
128                 message = formatter.format(message);
129                 break;
130             case RAW:
131                 break;
132             case PLAIN:
133                 // todo strip < > tags
134                 break;
135             default:
136                 throw new InvalidArgumentException(format("Unknown output type given (%s)", type));
137         }
138 
139         doWrite(message, newline);
140     }
141 
142     override public void writeln(string message)
143     {
144         write(message, true);
145     }
146 
147     override public void writeln(string message, OutputType type)
148     {
149         write(message, true, type);
150     }
151 
152     /**
153      * Writes a message to the output.
154      *
155      * @param message A message to write to the output
156      * @param newline Whether to add a newline or not
157      */
158     abstract protected void doWrite(string message, bool newline);
159 }