{-# 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