ip-1.7.8: test/IPv4DecodeText1.hs
module IPv4DecodeText1 where
import Control.Monad
import Data.Bits (shiftL, (.|.))
import qualified Data.Text as Text
import Data.Text.Internal (Text (..))
import qualified Data.Text.Read as TextRead
import Data.Word
import Net.Types
stripDecimal :: Text -> Either String Text
stripDecimal t = case Text.uncons t of
Nothing -> Left "expected a dot but input ended instead"
Just (c, tnext) ->
if c == '.'
then Right tnext
else Left "expected a dot but found a different character"
{-# INLINE stripDecimal #-}
decodeIPv4TextEither :: Text -> Either String Word32
decodeIPv4TextEither t1' = do
(a, t2) <- TextRead.decimal t1'
t2' <- stripDecimal t2
(b, t3) <- TextRead.decimal t2'
t3' <- stripDecimal t3
(c, t4) <- TextRead.decimal t3'
t4' <- stripDecimal t4
(d, t5) <- TextRead.decimal t4'
when (not (Text.null t5)) (Left "expected end of text but it continued instead")
if a > 255 || b > 255 || c > 255 || d > 255
then Left ipOctetSizeErrorMsg
else Right (fromOctets' a b c d)
decodeText :: Text -> Maybe IPv4
decodeText t = case decodeIPv4TextEither t of
Left _ -> Nothing
Right w -> Just (IPv4 w)
ipOctetSizeErrorMsg :: String
ipOctetSizeErrorMsg = "All octets in an IPv4 address must be between 0 and 255"
fromOctets' :: Word32 -> Word32 -> Word32 -> Word32 -> Word32
fromOctets' a b c d =
( shiftL a 24
.|. shiftL b 16
.|. shiftL c 8
.|. d
)