module Data.ByteString.Read.Integral
( integral'
, integral
, int
) where
import Data.ByteString(ByteString)
import qualified Data.ByteString as S
import Data.ByteString.Unsafe
import Data.Proxy.Compat
import GHC.TypeLits.Compat
import Data.ByteString.Read.Class
integral_ :: (Radix b, Num n) => proxy b -> ByteString -> (n, Int, ByteString)
integral_ pn = loop 0 0
where
loop !i !d !s
| S.null s = (i, d, s)
| not (isDigit pn (unsafeHead s)) = (i, d, s)
| otherwise = loop
(i * fromIntegral (natVal pn) + (fromIntegral $ unsafeToDigit pn (unsafeHead s)))
(d+1) (unsafeTail s)
integral' :: (Radix b, Num n) => proxy b -> ByteString -> Maybe (n, ByteString)
integral' pn s0 = case integral_ pn s0 of
(_, 0, _) -> Nothing
(n, _, s) -> Just (n, s)
integral :: Num n => ByteString -> Maybe (n, ByteString)
integral = integral' (Proxy :: Proxy 10)
int :: ByteString -> Maybe (Int, ByteString)
int = integral