module Data.Thyme.Format.Internal where
import Prelude
import Control.Applicative
import Data.Attoparsec.ByteString.Char8 (Parser)
import qualified Data.Attoparsec.ByteString.Char8 as P
import qualified Data.ByteString.Char8 as S
import Data.Char
import Data.Int
#if MIN_VERSION_bytestring(0,10,0)
# if MIN_VERSION_bytestring(0,10,2)
import qualified Data.ByteString.Builder as B
# else
import qualified Data.ByteString.Lazy.Builder as B
# endif
import qualified Data.ByteString.Lazy as L
#else
import qualified Data.ByteString.UTF8 as U8
#endif
utf8Char :: Char -> S.ByteString
utf8String :: String -> S.ByteString
#if MIN_VERSION_bytestring(0,10,0)
utf8Char = L.toStrict . B.toLazyByteString . B.charUtf8
utf8String = L.toStrict . B.toLazyByteString . B.stringUtf8
#else
utf8Char = U8.fromString . (:[])
utf8String = U8.fromString
#endif
shows02 :: Int -> String -> String
shows02 n = if n < 10 then (:) '0' . shows n else shows n
shows_2 :: Int -> String -> String
shows_2 n = if n < 10 then (:) ' ' . shows n else shows n
shows03 :: Int -> ShowS
shows03 n
| n < 10 = (++) "00" . shows n
| n < 100 = (++) "0" . shows n
| otherwise = shows n
shows04 :: Int -> String -> String
shows04 n
| n < 10 = (++) "000" . shows n
| n < 100 = (++) "00" . shows n
| n < 1000 = (++) "0" . shows n
| otherwise = shows n
fills06 :: Int64 -> ShowS
fills06 n
| n < 10 = (++) "00000"
| n < 100 = (++) "0000"
| n < 1000 = (++) "000"
| n < 10000 = (++) "00"
| n < 100000 = (++) "0"
| otherwise = id
drops0 :: Int64 -> ShowS
drops0 n = case divMod n 10 of
(q, 0) -> drops0 q
_ -> shows n
indexOf :: [String] -> Parser Int
indexOf = P.choice . zipWith (\ i s -> i <$ P.string (S.pack s)) [0..]
indexOfCI :: [String] -> Parser Int
indexOfCI = P.choice . zipWith (\ i s -> i <$ stringCI s) [0..]
stringCI :: String -> Parser ()
stringCI = foldl (\ p c -> p *> charCI c) (pure ())
charCI :: Char -> Parser ()
charCI c = if u == l then charU8 c else charU8 l <|> charU8 u where
l = toLower c
u = toUpper c
charU8 :: Char -> Parser ()
charU8 c = () <$ P.string (utf8Char c)
negative :: Parser Int64 -> Parser Int64
negative p = ($) <$> (negate <$ P.char '-' <|> pure id) <*> p
dec0 :: Int -> Parser Int
dec0 n = either fail return . P.parseOnly P.decimal =<< P.take n
dec_ :: Int -> Parser Int
dec_ n = either fail return . P.parseOnly P.decimal
=<< S.dropWhile isSpace <$> P.take n