iCalendar-0.4: Text/ICalendar/Parser.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeSynonymInstances #-}
module Text.ICalendar.Parser
( parseICalendar
, parseICalendarFile
, parseICal
, parseICalFile
, DecodingFunctions(..)
) where
import Control.Applicative
import Control.Monad
import Control.Monad.Error
import Control.Monad.RWS (runRWS)
import Data.ByteString.Lazy (ByteString)
import qualified Data.ByteString.Lazy.Char8 as B
import Data.Monoid
import Prelude
import Text.Parsec.ByteString.Lazy ()
import Text.Parsec.Pos
import Text.Parsec.Prim hiding (many, (<|>))
import Text.Parsec.Text.Lazy ()
import Text.ICalendar.Parser.Common
import Text.ICalendar.Parser.Components
import Text.ICalendar.Parser.Content
import Text.ICalendar.Types
-- | Parse a ByteString containing iCalendar data.
--
-- Returns either an error, or a tuple of the result and a list of warnings.
parseICalendar :: DecodingFunctions
-> FilePath -- ^ Used in error messages.
-> ByteString
-> Either String ([VCalendar], [String])
parseICalendar s f bs = do
a <- either (Left . show) Right $ runParser parseToContent s f bs
when (null a) $ throwError "Missing content."
let xs = map (runCP s . parseVCalendar) a
(x, w) <- ((flip.).) flip foldM ([], []) xs $ \(x, ws) (g, (pos, _), w) ->
case g of
Left e -> Left $ show pos ++ ": " ++ e
Right y -> Right (y:x, w <> ws)
return (x, w)
-- | Deprecated synonym for parseICalendar
parseICal :: DecodingFunctions
-> FilePath
-> ByteString
-> Either String ([VCalendar], [String])
parseICal = parseICalendar
{-# DEPRECATED parseICal "Use parseICalendar instead" #-}
-- | Parse an iCalendar file.
parseICalendarFile :: DecodingFunctions
-> FilePath
-> IO (Either String ([VCalendar], [String]))
parseICalendarFile s f = parseICal s f <$> B.readFile f
-- | Deprecated synonym for parseICalendarFile
parseICalFile :: DecodingFunctions
-> FilePath
-> IO (Either String ([VCalendar], [String]))
parseICalFile = parseICalendarFile
{-# DEPRECATED parseICalFile "Use parseICalendarFile instead" #-}
runCP :: DecodingFunctions -> ContentParser a
-> (Either String a, (SourcePos, [Content]), [String])
runCP s = ((flip .) . flip) runRWS s (undefined, undefined) . runErrorT