1 module mage.util.stream;
2 
3 import mage;
4 
5 mixin template StreamWriteln()
6 {
7   string newLine = "\n";
8   int indentation = 0;
9   string indentString = "  ";
10 
11   /// Increase indentation. Does not write.
12   void indent() {
13     ++indentation;
14   }
15 
16   /// Decrease indentation to a minimum of 0. Does not write.
17   void dedent() {
18     import std.algorithm : max;
19     indentation = max(indentation - 1, 0);
20   }
21 
22   void writeln(string s = null)
23   {
24     if(s) this.write(s);
25     this.write(this.newLine);
26     foreach(i; 0..this.indentation) {
27       this.write(this.indentString);
28     }
29   }
30 }
31 
32 unittest {
33   struct S { mixin StreamWriteln; void write(...){} }
34   S s;
35   assert(s.indentation == 0);
36   s.dedent();
37   assert(s.indentation == 0);
38   s.indent();
39   assert(s.indentation == 1);
40   s.indent();
41   assert(s.indentation == 2);
42   s.dedent();
43   assert(s.indentation == 1);
44   s.dedent();
45   assert(s.indentation == 0);
46   s.dedent();
47   assert(s.indentation == 0);
48 }
49 
50 struct FileStream
51 {
52   import std.stdio : File;
53 
54   File file;
55 
56   mixin StreamWriteln;
57 
58   this(Path p, string mode = "rb") {
59     file = p.open(mode);
60   }
61 
62   void write(string s)
63   {
64     file.write(s);
65   }
66 }
67 
68 struct StringStream
69 {
70   import std.format;
71   
72   string content;
73 
74   mixin StreamWriteln;
75 
76   this(string initial = "") {
77     content = initial;
78   }
79 
80   void write(string s)
81   {
82     content ~= s;
83   }
84 }