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 }