{-# LANGUAGE RecordWildCards #-} module TableParser(MailRecord(..), parseBString, parseTable) where 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 import qualified Data.Time.Calendar as D import qualified Data.ByteString as B import Control.Monad(void) data MailRecord = MailRecord { date :: D.Day, voice1 :: LT.Text, voice2 :: LT.Text, song1 :: LT.Text, song2 :: LT.Text, announcement :: LT.Text } deriving (Show) seperator :: Char seperator = '\t' sepParser :: P.Parser () sepParser = void $ P.char seperator textCellParser :: P.Parser LT.Text textCellParser = fmap LT.pack $ P.many $ P.noneOf [seperator,'\n','\r'] 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 voice1 <- textCellParser sepParser voice2 <- textCellParser sepParser song1 <- textCellParser sepParser song2 <- textCellParser sepParser announcement <- textCellParser return $ MailRecord{..} parseFirstRow :: P.Parser () parseFirstRow = void (P.string "Datum\tStimmprobe 1\tStimmprobe 2\tLied 1\tLied 2\tWeitere Ansagen" >> P.endOfLine) parseTable :: P.Parser [MailRecord] parseTable = do parseFirstRow x <- parseRow `P.sepEndBy` P.endOfLine P.eof return x textToMailRecord :: ST.Text -> Either String [MailRecord] 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 Left x -> Left $ show x Right x -> Right x