1 module beard.io;
2 
3 import beard.termcolor;
4 import std.stdio;
5 import std.typecons : isTuple;
6 
7 immutable INDENT_STR = "    ";
8 
9 void printIndent(S)(S stream, int indent) {
10     for (int i = 0; i < indent; ++i) stream.write(INDENT_STR);
11 }
12 
13 private void _print(S, H)(S stream, int indent, H h) {
14     static if (isTuple!H) {
15         stream.write("(\n");
16         printIndent(stream, indent + 1);
17         printIndented(stream, indent + 1, h[0]);
18         foreach(value; h[1..$]) {
19             stream.write(",\n");
20             printIndent(stream, indent + 1);
21             printIndented(stream, indent + 1, value);
22         }
23         stream.writeln();
24         printIndent(stream, indent);
25         stream.write(')');
26     }
27     else static if (is(H : string)) {
28         stream.write(h);
29     }
30     else static if (std.traits.isArray!(H)) {
31         if (! h.length) {
32             stream.write("[]");
33             return;
34         }
35 
36         stream.write("[\n");
37         printIndent(stream, indent + 1);
38         printIndented(stream, indent + 1, h[0]);
39         foreach(value; h[1..$]) {
40             stream.write(",\n");
41             printIndent(stream, indent + 1);
42             printIndented(stream, indent + 1, value);
43         }
44 
45         stream.writeln();
46         printIndent(stream, indent);
47         stream.write(']');
48     }
49     else static if (__traits(hasMember, H, "printTo")) {
50         // better than compiles check in case user messes up a templated
51         // printTo and then wonders why it isn't called
52         static if (is (H : Object)) {
53             if (! h) {
54                 stream.write("null");
55                 return;
56             }
57         }
58         h.printTo(indent, stream);
59     }
60     else stream.write(h);
61 }
62 
63 private void printTail(S, H, T...)(S stream, int indent, H h, T t) {
64     stream.write(' ');
65     _print(stream, indent, h);
66     printTail(stream, indent, t);
67 }
68 
69 private void printTail(S)(S stream, int indent) {}
70 
71 void printIndented(S, H, T...)(S stream, int indent, H h, T t) {
72     _print(stream, indent, h);
73     printTail(stream, indent, t);
74 }
75 
76 void printIndented(H...)(int indent, H h) {
77     printIndented(stdout, h);
78 }
79 
80 // todo: check if first argument is stream or not
81 void print(T...)(T t) {
82     printIndented(stdout, 0, t);
83 }
84 
85 void println(T...)(T t) {
86     print(t);
87     writeln();
88 }
89 // vim:ts=4 sw=4