1-----------------------------------------------------------------------------
2-- |
3-- Module      :  Distribution.ReadE
4-- Copyright   :  Jose Iborra 2008
5-- License     :  BSD3
6--
7-- Maintainer  :  cabal-devel@haskell.org
8-- Portability :  portable
9--
10-- Simple parsing with failure
11
12module Distribution.ReadE (
13   -- * ReadE
14   ReadE(..), succeedReadE, failReadE,
15   -- * Projections
16   readEOrFail,
17   parsecToReadE,
18  ) where
19
20import Distribution.Compat.Prelude
21import Prelude ()
22
23import Distribution.Parsec
24import Distribution.Parsec.FieldLineStream
25
26-- | Parser with simple error reporting
27newtype ReadE a = ReadE {runReadE :: String -> Either ErrorMsg a}
28type ErrorMsg   = String
29
30instance Functor ReadE where
31  fmap f (ReadE p) = ReadE $ \txt -> case p txt of
32                                       Right a  -> Right (f a)
33                                       Left err -> Left err
34
35succeedReadE :: (String -> a) -> ReadE a
36succeedReadE f = ReadE (Right . f)
37
38failReadE :: ErrorMsg -> ReadE a
39failReadE = ReadE . const . Left
40
41readEOrFail :: ReadE a -> String -> a
42readEOrFail r = either error id . runReadE r
43
44parsecToReadE :: (String -> ErrorMsg) -> ParsecParser a -> ReadE a
45parsecToReadE err p = ReadE $ \txt ->
46    case runParsecParser p "<parsecToReadE>" (fieldLineStreamFromString txt) of
47        Right x -> Right x
48        Left _e -> Left (err txt)
49-- TODO: use parsec error to make 'ErrorMsg'.
50