21GramConsulting/Beton

CSV Convenience

Opened this issue · 0 comments

Add a better, professional and well tested version of this quick hackery I made a few days ago.

The idea is that anything that is:

  • a RangeReplacableCollection,
  • who's elements are RangeReplacableCollections
  • who's subitems are ExpressibleByStringLiteral

can all be initialized from a CSV.

The additional stuff to add:

  • Anything that is expressible by an array literal
  • Bunch of tests
  • Bunch of examples
import Foundation

typealias RawCsvTable = [[String]]

extension RangeReplaceableCollection
where
  Element: RangeReplaceableCollection,
  Element.Element: ExpressibleByStringLiteral,
  Element.Element.StringLiteralType == String
{

  typealias CsvTable = Self
  typealias CsvRow = Element
  typealias CsvCell = Element.Element

  init?(fromCsv url: URL) {
    guard let raw = try? String(contentsOf: url) else { return nil }
    self.init(
      raw
        .components(separatedBy: .newlines)
        .map { .init($0.components(separatedBy: ";").map { CsvCell(stringLiteral: $0) }) }
    )
  }

}