-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #11 from sergkh/table-view
Customizable output formats
- Loading branch information
Showing
7 changed files
with
237 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,31 @@ | ||
enum FileType: CaseIterable { | ||
case csv | ||
case table // own table format | ||
case sql | ||
case cassandraSql | ||
|
||
static func hasOuterBorders(type: FileType) -> Bool { | ||
switch type { | ||
case .table: | ||
return true | ||
case .sql: | ||
return true | ||
default: | ||
return false | ||
} | ||
} | ||
|
||
static func outFormat(strFormat: String?) throws -> FileType { | ||
if let strFormat = strFormat { | ||
if strFormat == "csv" { | ||
return .csv | ||
} else if strFormat == "table" { | ||
return .table | ||
} else { | ||
throw RuntimeError("Unknown output format \(strFormat)") | ||
} | ||
} else { | ||
return .table | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
|
||
import Foundation | ||
|
||
let newLine = "\n".data(using: .utf8)! | ||
|
||
protocol TablePrinter { | ||
func writeHeader(header: Header) | ||
func writeRow(row: Row) | ||
func flush() | ||
} | ||
|
||
class CsvTablePrinter: TablePrinter { | ||
private let delimeter: String | ||
private let outHandle: FileHandle | ||
|
||
init(delimeter: String, outHandle: FileHandle) { | ||
self.delimeter = delimeter | ||
self.outHandle = outHandle | ||
} | ||
|
||
func writeHeader(header: Header) { | ||
self.outHandle.write(header.cols.joined(separator: delimeter).data(using: .utf8)!) | ||
self.outHandle.write(newLine) | ||
} | ||
|
||
func writeRow(row: Row) { | ||
self.outHandle.write(row.components.joined(separator: delimeter).data(using: .utf8)!) | ||
self.outHandle.write(newLine) | ||
} | ||
|
||
func flush() {} | ||
} | ||
|
||
class CustomFormatTablePrinter: TablePrinter { | ||
private let format: Format | ||
private let outHandle: FileHandle | ||
|
||
init(format: Format, outHandle: FileHandle) { | ||
self.format = format | ||
self.outHandle = outHandle | ||
} | ||
|
||
// no header needed | ||
func writeHeader(header: Header) {} | ||
|
||
func writeRow(row: Row) { | ||
self.outHandle.write(self.format.fillData(rows: [row])) | ||
self.outHandle.write(newLine) | ||
} | ||
|
||
func flush() {} | ||
} | ||
|
||
class PrettyTablePrinter: TablePrinter { | ||
private let outHandle: FileHandle | ||
private var columnWidths: [Int] = [] | ||
private var header: Header? | ||
private var cachedRows: [Row] = [] | ||
|
||
init(outHandle: FileHandle) { | ||
self.outHandle = outHandle | ||
} | ||
|
||
func writeHeader(header: Header) { | ||
self.header = header | ||
self.adjustColumns(row: header.cols) | ||
} | ||
|
||
func writeRow(row: Row) { | ||
self.cachedRows.append(row) | ||
self.adjustColumns(row: row.components) | ||
} | ||
|
||
func flush() { | ||
let topBorder = "╭" + self.columnWidths.map( { String(repeating: "─", count: $0 + 2)}).joined(separator: "┬") + "╮\n" | ||
self.outHandle.write(topBorder.data(using: .utf8)!) | ||
|
||
if let header = self.header { | ||
self.outHandle.write(formatRow(header.cols).data(using: .utf8)!) | ||
|
||
let headerBorder = "├" + self.columnWidths.map( { String(repeating: "─", count: $0 + 2)}).joined(separator: "┼") + "┤\n" | ||
self.outHandle.write(headerBorder.data(using: .utf8)!) | ||
} | ||
|
||
for row in self.cachedRows { | ||
self.outHandle.write(formatRow(row.components).data(using: .utf8)!) | ||
} | ||
|
||
let bottomBorder = "╰" + self.columnWidths.map( { String(repeating: "─", count: $0 + 2)}).joined(separator: "┴") + "╯\n" | ||
self.outHandle.write(bottomBorder.data(using: .utf8)!) | ||
} | ||
|
||
private func adjustColumns(row: [String]) { | ||
if self.columnWidths.isEmpty { | ||
self.columnWidths = row.map { $0.count } | ||
} else { | ||
|
||
if (row.count != self.columnWidths.count) { | ||
fatalError("Row \(row) has irregular size. Table output is not possible, please use CSV format") | ||
} | ||
|
||
for (i, col) in row.enumerated() { | ||
self.columnWidths[i] = max(self.columnWidths[i], col.count) | ||
} | ||
} | ||
} | ||
|
||
private func formatRow(_ row: [String]) -> String { | ||
return row.enumerated().map { (idx, col) in | ||
let padding = String(repeating: " ", count: self.columnWidths[idx] - col.count) | ||
return "│ " + col + padding + " " | ||
}.joined(separator: "") + "│\n" | ||
} | ||
} |
Oops, something went wrong.