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 qualified Data.ByteString.Builder as S
import qualified Data.ByteString.Lazy as L
import Data.Char
import Data.Int
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
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 (L.toStrict . S.toLazyByteString . S.charUtf8 $ 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