module Net.IPv4.Unnormalized
  ( unnormalizedDecodeRange
  ) where

import Data.Text (Text)
import Net.Types (IPv4, IPv4Range(..), Mac)

import qualified Net.IPv4 as IPv4
import qualified Data.Attoparsec.Text as AT

-- Decode an 'IPv4Range' from 'Text'.
unnormalizedDecodeRange :: Text -> Maybe IPv4Range
unnormalizedDecodeRange :: Text -> Maybe IPv4Range
unnormalizedDecodeRange =
  (String -> Maybe IPv4Range)
-> (IPv4Range -> Maybe IPv4Range)
-> Either String IPv4Range
-> Maybe IPv4Range
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe IPv4Range -> String -> Maybe IPv4Range
forall a b. a -> b -> a
const Maybe IPv4Range
forall a. Maybe a
Nothing) IPv4Range -> Maybe IPv4Range
forall a. a -> Maybe a
Just (Either String IPv4Range -> Maybe IPv4Range)
-> (Text -> Either String IPv4Range) -> Text -> Maybe IPv4Range
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser IPv4Range -> Text -> Either String IPv4Range
forall a. Parser a -> Text -> Either String a
AT.parseOnly (Parser IPv4Range
unnormalizedParserRange Parser IPv4Range -> Parser Text () -> Parser IPv4Range
forall a b. Parser Text a -> Parser Text b -> Parser Text a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
forall t. Chunk t => Parser t ()
AT.endOfInput)

-- The same this as parserRange except that it does not
-- do any normalization of the range.
unnormalizedParserRange :: AT.Parser IPv4Range
unnormalizedParserRange :: Parser IPv4Range
unnormalizedParserRange = do
  IPv4
ip <- Parser IPv4
IPv4.parser
  Char
_ <- Char -> Parser Char
AT.char Char
'/'
  Word8
theMask <- Parser Word8
forall a. Integral a => Parser a
AT.decimal Parser Word8 -> (Word8 -> Parser Word8) -> Parser Word8
forall a b. Parser Text a -> (a -> Parser Text b) -> Parser Text b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Word8 -> Parser Word8
forall {a} {m :: * -> *}. (Ord a, Num a, MonadFail m) => a -> m a
limitSize
  IPv4Range -> Parser IPv4Range
forall a. a -> Parser Text a
forall (m :: * -> *) a. Monad m => a -> m a
return (IPv4 -> Word8 -> IPv4Range
IPv4Range IPv4
ip Word8
theMask)
  where
  limitSize :: a -> m a
limitSize a
i =
    if a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
32
      then String -> m a
forall a. String -> m a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"An IPv4 range length must be between 0 and 32"
      else a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
i