choirMail/app/TableParser.hs

88 lines
2.1 KiB
Haskell
Raw Permalink Normal View History

{-# LANGUAGE RecordWildCards #-}
2022-11-08 20:16:34 +01:00
module TableParser(MailRecord(..), parseBString, parseTable) where
2022-11-08 20:16:34 +01:00
import qualified Text.Parsec as P
-- import qualified Text.Parsec.Char as P
import qualified Text.Parsec.Text as P
import qualified Data.Text.Lazy as LT
import qualified Data.Text as ST
import qualified Data.Text.Encoding as ST
2022-11-08 20:16:34 +01:00
import qualified Data.Time.Calendar as D
import qualified Data.ByteString as B
import Control.Monad(void)
2022-11-08 20:16:34 +01:00
data MailRecord = MailRecord {
date :: D.Day,
2023-12-10 19:35:58 +01:00
voices :: LT.Text,
songs :: LT.Text,
notes :: LT.Text,
announcement :: LT.Text
2022-11-08 20:16:34 +01:00
} deriving (Show)
seperator :: Char
2023-12-10 19:35:58 +01:00
seperator = ';'
2022-11-08 20:16:34 +01:00
sepParser :: P.Parser ()
sepParser = void $ P.char seperator
textCellParser :: P.Parser LT.Text
textCellParser = fmap LT.pack $ P.many $ P.noneOf [seperator,'\n','\r']
2022-11-08 20:16:34 +01:00
dateCellParser :: P.Parser D.Day
dateCellParser = do
year <- parseYear
_ <- P.char '-'
month <- parseMonth
_ <- P.char '-'
day <- parseDay
return $ D.fromGregorian year month day
parseYear :: P.Parser Integer
parseYear = read <$> P.count 4 P.digit
parseMonth :: P.Parser Int
parseMonth = read <$> P.count 2 P.digit
parseDay :: P.Parser Int
parseDay = read <$> P.count 2 P.digit
parseRow :: P.Parser MailRecord
parseRow = do
date <- dateCellParser
sepParser
2023-12-10 19:35:58 +01:00
voices <- textCellParser
2022-11-08 20:16:34 +01:00
sepParser
2023-12-10 19:35:58 +01:00
songs <- textCellParser
2022-11-08 20:16:34 +01:00
sepParser
2023-12-10 19:35:58 +01:00
notes <- textCellParser
2022-11-08 20:16:34 +01:00
sepParser
announcement <- textCellParser
return $ MailRecord{..}
2022-11-08 20:16:34 +01:00
parseFirstRow :: P.Parser ()
2023-12-10 19:35:58 +01:00
parseFirstRow = void (P.string "Datum;Stimmproben;Lieder;Noten;Weitere Ansagen" >> P.endOfLine)
2022-11-08 20:16:34 +01:00
parseTable :: P.Parser [MailRecord]
parseTable = do
parseFirstRow
x <- parseRow `P.sepEndBy` P.endOfLine
P.eof
return x
textToMailRecord :: ST.Text -> Either String [MailRecord]
2022-11-08 20:16:34 +01:00
textToMailRecord t = case P.parse parseTable "" t of
Left x -> Left $ show x
Right x -> Right x
parseBString :: B.ByteString -> Either String [MailRecord]
parseBString t = do
text <- toText t
textToMailRecord text
toText :: B.ByteString -> Either String ST.Text
toText t = case ST.decodeUtf8' t of
2022-11-08 20:16:34 +01:00
Left x -> Left $ show x
Right x -> Right x