Implement TSV internally, remove the "csv" package dependency.
[match/match.git] / program / TSV.hs
1 module TSV (
2         parseTSV, formatTSV
3 ) where
4 import Data.List
5
6 -- Simple implementation of tab-separated values with a trailing newline and no
7 -- quoting support.
8
9 splitList :: Eq a => a -> Bool -> [a] -> [[a]]
10 splitList delim terminated =
11         let sl [] | terminated = []
12             sl l = case break (== delim) l of
13                    (hh, []) -> [hh]
14                    (hh, {-delim-} _ : t) -> hh : sl t
15         in sl
16
17 -- We use the Eq only to check the validity...
18 joinList :: Eq a => a -> Bool -> [[a]] -> [a]
19 joinList delim terminated l =
20         if any (any (== delim)) l then error "joinList: item contains delimiter"
21         else if terminated
22         then concatMap (++ [delim]) l
23         else intercalate [delim] l
24
25 type TSV = [[String]]
26
27 formatTSV :: TSV -> String
28 formatTSV = joinList '\n' True . map (joinList '\t' False)
29
30 parseTSV :: String -> TSV
31 parseTSV = map (splitList '\t' False) . splitList '\n' True