Initial commit

This commit is contained in:
Simon Brooke 2020-01-27 10:31:03 +00:00
commit f8490e2d23
9 changed files with 455 additions and 0 deletions

44
src/csv2edn/core.clj Normal file
View file

@ -0,0 +1,44 @@
(ns csv2edn.core
(:require [clojure.java.io :as io]
[clojure.tools.cli :refer [parse-opts]]
[csv2edn.csv2edn :refer [csv2edn *options*]])
(:gen-class))
(def cli-options
[["-h" "--help" "Print this message and exit."]
["-i" "--input INPUT" "The path name of the CSV file to be read.
If no input file is specified, input will be read from standard input."
:validate [#(and
(.exists (io/file %))
(.canRead (io/file %)))
"Could not find input file"]]
["-o" "--output OUTPUT" "The path name of the EDN file to be written.
If no output file is specified, output will be written to standard output."]
["-s" "--separator SEPARATOR"
"The character to treat as a separator in the CSV file"
:parse-fn #(first (str %))
:default \,]
])
(defn -main
"I don't do a whole lot ... yet."
[& opts]
(let [args (parse-opts opts cli-options)]
(println
(if
(:help (:options args))
(:summary args) "")
(if (:errors args)
(apply str (interpose "; " (:errors args))) ""))
(if-not (:help (:options args))
(binding [*options* (:options args)]
(doall
(csv2edn
(or
(:input *options*)
(io/reader *in*))
(or (:output *options*) (io/writer *out*)))
)))))

32
src/csv2edn/csv2edn.clj Normal file
View file

@ -0,0 +1,32 @@
(ns csv2edn.csv2edn
(:require [clojure.data.csv :as csv]
[clojure.java.io :as io]
[clojure.pprint :refer [pprint]]
[clojure.string :refer [lower-case]]))
(def ^:dynamic *options* {:separator \,})
(defn maybe-read
"If a string represents an integer or real, we'd really like to have that
integer or real in our data rather than a string representation of it."
[^String s]
(try
(read-string s)
(catch Exception _ s)))
(defn csv2edn
"Read a CSV stream from the reader or filename `in`, and write corresponding
EDN to the reader or filname `out`. Assume column headers are in row 1"
[from to]
(let [data (with-open [reader (if (string? from)(io/reader from) from)]
(doall
(csv/read-csv
reader
:separator (:separator *options*))))
headers (map #(keyword (lower-case %)) (first data))]
(with-open [writer (if (string? to) (io/writer to) to)]
(pprint
(map
#(zipmap headers (map maybe-read %))
(rest data))
writer))))