, assertTimeOfDayIsGood
, optionMaybe
+ , finishOff
+
+ , parseAttempt
+ , parseAttempt'
)
where
import Blaze.ByteString.Builder.ByteString as B
import Blaze.Text.Int as BT
import Control.Applicative
+import Control.Exception.Base
import Control.Monad
-import Data.Ascii (AsciiBuilder)
+import Control.Monad.Unicode
+import Data.Ascii (Ascii, AsciiBuilder)
import qualified Data.Ascii as A
+import Data.Attempt
import Data.Attoparsec.Char8 as P
+import Data.ByteString (ByteString)
+import Data.Char
import Data.Monoid.Unicode
import Data.Fixed
import Data.Time
return (n1 * 10 + n2)
digit' ∷ Num n ⇒ Parser n
-digit' = fromC <$> P.digit
-
-fromC ∷ Num n ⇒ Char → n
-fromC '0' = 0
-fromC '1' = 1
-fromC '2' = 2
-fromC '3' = 3
-fromC '4' = 4
-fromC '5' = 5
-fromC '6' = 6
-fromC '7' = 7
-fromC '8' = 8
-fromC '9' = 9
-fromC _ = undefined
+{-# INLINE digit' #-}
+digit' = fromIntegral <$> fromC <$> P.digit
+ where
+ {-# INLINE fromC #-}
+ fromC c = ord c - ord '0'
show4digitsTZ ∷ TimeZone → AsciiBuilder
show4digitsTZ tz
(year, month, day) = toGregorian gregDay
in
unless (givenWD ≡ correctWD)
- $ fail
+ ∘ fail
$ concat [ "Gregorian day "
, show year
, "-"
{-# INLINE optionMaybe #-}
optionMaybe p
= option Nothing (Just <$> p)
+
+finishOff ∷ Parser α → Parser α
+{-# INLINE finishOff #-}
+finishOff = ((endOfInput *>) ∘ return =≪)
+
+parseAttempt ∷ Exception e
+ ⇒ (String → e)
+ → Parser α
+ → ByteString
+ → Attempt α
+{-# INLINEABLE parseAttempt #-}
+parseAttempt f p bs
+ = case parseOnly (finishOff p) bs of
+ Right α → Success α
+ Left e → Failure $ f e
+
+parseAttempt' ∷ Parser α → Ascii → Attempt α
+{-# INLINE parseAttempt' #-}
+parseAttempt' p a = parseAttempt h p bs
+ where
+ h ∷ String → StringException
+ h _ = StringException $ A.toString a
+
+ bs ∷ ByteString
+ bs = A.toByteString a