1 /** 2 Copyright: Copyright (c) 2018, Joakim Brännström. All rights reserved. 3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 */ 6 module distssh.table; 7 8 import logger = std.experimental.logger; 9 import std.exception : collectException; 10 11 @safe: 12 13 struct Table(int columnsNr) { 14 alias Row = string[columnsNr]; 15 16 Row heading_; 17 Row[] rows; 18 ulong[columnsNr] columnWidth; 19 20 this(const Row heading) { 21 this.heading = heading; 22 updateColumns(heading); 23 } 24 25 void heading(const Row r) { 26 heading_ = r; 27 updateColumns(r); 28 } 29 30 void put(const Row r) { 31 rows ~= r; 32 updateColumns(r); 33 } 34 35 import std.format : FormatSpec; 36 37 void toString(Writer, Char)(scope Writer w, FormatSpec!Char fmt) const { 38 import std.ascii : newline; 39 import std.range : enumerate, repeat; 40 import std.format : formattedWrite; 41 import std.range.primitives : put; 42 43 immutable sep = "|"; 44 immutable lhs_sep = "| "; 45 immutable mid_sep = " | "; 46 immutable rhs_sep = " |"; 47 48 void printRow(const ref Row r) { 49 foreach (const r_; r[].enumerate) { 50 if (r_.index == 0) 51 put(w, lhs_sep); 52 else 53 put(w, mid_sep); 54 formattedWrite(w, "%-*s", columnWidth[r_.index], r_.value); 55 } 56 put(w, rhs_sep); 57 put(w, newline); 58 } 59 60 printRow(heading_); 61 62 immutable dash = "-"; 63 foreach (len; columnWidth) { 64 put(w, sep); 65 put(w, repeat(dash, len + 2)); 66 } 67 put(w, sep); 68 put(w, newline); 69 70 foreach (const ref r; rows) { 71 printRow(r); 72 } 73 } 74 75 private void updateColumns(const ref Row r) nothrow { 76 import std.algorithm : filter, count, map; 77 import std.range : enumerate; 78 import std.uni : byGrapheme; 79 import std.typecons : tuple; 80 81 try { 82 foreach (a; r[].enumerate 83 .map!(a => tuple(a.index, a.value.byGrapheme.count)) 84 .filter!(a => a[1] > columnWidth[a[0]])) { 85 columnWidth[a[0]] = a[1]; 86 } 87 } catch (Exception e) { 88 logger.warning(e.msg).collectException; 89 } 90 } 91 }