Implement TSV internally, remove the "csv" package dependency.
[match/match.git] / program / TSV.hs
diff --git a/program/TSV.hs b/program/TSV.hs
new file mode 100644 (file)
index 0000000..9b2cf9f
--- /dev/null
@@ -0,0 +1,31 @@
+module TSV (
+       parseTSV, formatTSV
+) where
+import Data.List
+
+-- Simple implementation of tab-separated values with a trailing newline and no
+-- quoting support.
+
+splitList :: Eq a => a -> Bool -> [a] -> [[a]]
+splitList delim terminated =
+       let sl [] | terminated = []
+           sl l = case break (== delim) l of
+                  (hh, []) -> [hh]
+                  (hh, {-delim-} _ : t) -> hh : sl t
+       in sl
+
+-- We use the Eq only to check the validity...
+joinList :: Eq a => a -> Bool -> [[a]] -> [a]
+joinList delim terminated l =
+       if any (any (== delim)) l then error "joinList: item contains delimiter"
+       else if terminated
+       then concatMap (++ [delim]) l
+       else intercalate [delim] l
+
+type TSV = [[String]]
+
+formatTSV :: TSV -> String
+formatTSV = joinList '\n' True . map (joinList '\t' False)
+
+parseTSV :: String -> TSV
+parseTSV = map (splitList '\t' False) . splitList '\n' True