hw-ip 0.3.0 → 0.4.0
raw patch · 4 files changed
+56/−14 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- HaskellWorks.Data.Network.Ip.Internal: infixl 2 #<*>#
+ HaskellWorks.Data.Network.Ip.Internal: d :: Int -> Parser Word8
+ HaskellWorks.Data.Network.Ip.Internal: ds :: Int -> Int -> Parser Word8
+ HaskellWorks.Data.Network.Ip.Internal: infixl 4 #<*>#
+ HaskellWorks.Data.Network.Ip.Internal: ipv4Block :: Parser (Word32, Word8)
+ HaskellWorks.Data.Network.Ip.Internal: ipv4NetMask :: Parser Word8
+ HaskellWorks.Data.Network.Ip.Type: instance GHC.Read.Read HaskellWorks.Data.Network.Ip.Type.Ipv4Block
Files
- hw-ip.cabal +1/−1
- src/HaskellWorks/Data/Network/Ip/Internal.hs +25/−13
- src/HaskellWorks/Data/Network/Ip/Type.hs +10/−0
- test/HaskellWorks/Data/Network/IpSpec.hs +20/−0
hw-ip.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack name: hw-ip-version: 0.3.0+version: 0.4.0 synopsis: Library for manipulating IP addresses and CIDR blocks description: Please see README.md category: Network
src/HaskellWorks/Data/Network/Ip/Internal.hs view
@@ -16,25 +16,18 @@ fromIntegral d {-# INLINE fourOctetsToWord32 #-} -infixl 2 #<*>#+infixl 4 #<*># (#<*>#) :: AP.Parser Word8 -> AP.Parser Word8 -> AP.Parser Word8 (#<*>#) pa pb = paste <$> pa <*> pb where paste a b = a * 10 + b octet :: AP.Parser Word8-octet = ((d12 #<*># d5 ) #<*># d05)- <|> ((d12 #<*># d04) #<*># d09)- <|> ((d1 #<*># d09) #<*># d09)- <|> ( d19 #<*># d09)- <|> d09- where d5 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (== '5')- d1 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (== '1')- d04 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (\c -> c >= '0' && c <= '4')- d05 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (\c -> c >= '0' && c <= '5')- d09 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (\c -> c >= '0' && c <= '9')- d19 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (\c -> c >= '1' && c <= '9')- d12 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (\c -> c >= '1' && c <= '2')+octet = (ds 1 2 #<*># d 5 ) #<*># ds 0 5+ <|> (ds 1 2 #<*># ds 0 4) #<*># ds 0 9+ <|> ( d 1 #<*># ds 0 9) #<*># ds 0 9+ <|> ds 1 9 #<*># ds 0 9+ <|> ds 0 9 ipv4Address :: AP.Parser Word32 ipv4Address = fourOctetsToWord32@@ -45,3 +38,22 @@ whitespace :: AP.Parser () whitespace = void $ many (AP.satisfy isSpace)++ipv4NetMask :: AP.Parser Word8+ipv4NetMask = d 3 #<*># ds 0 2+ <|> d 2 #<*># ds 0 9+ <|> d 1 #<*># ds 0 9+ <|> ds 0 9++d :: Int -> AP.Parser Word8+d c = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (== chr (c + 48))++ds :: Int -> Int -> AP.Parser Word8+ds c1 c2 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (\c -> c >= chr (c1 + 48) && c <= chr (c2 + 48))++ipv4Block :: AP.Parser (Word32, Word8)+ipv4Block = do+ addr <- ipv4Address+ _ <- AP.char '/'+ mask <- ipv4NetMask+ return (addr, mask)
src/HaskellWorks/Data/Network/Ip/Type.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE OverloadedStrings #-} module HaskellWorks.Data.Network.Ip.Type ( Ipv4Address(..)@@ -49,3 +50,12 @@ instance Show Ipv4Block where showsPrec _ (Ipv4Block b (Ipv4NetMask m)) = shows b . ('/':) . shows m++instance Read Ipv4Block where+ readsPrec :: Int -> String -> [(Ipv4Block, String)]+ readsPrec _ s = case AP.parseWith (return mempty) (I.whitespace *> I.ipv4Block) (T.pack s) of+ Just result -> case result of+ AP.Done i (a, m) -> [(Ipv4Block (Ipv4Address a) (Ipv4NetMask m), T.unpack i)]+ AP.Partial _ -> []+ AP.Fail a b c -> []+ Nothing -> []
test/HaskellWorks/Data/Network/IpSpec.hs view
@@ -3,25 +3,38 @@ module HaskellWorks.Data.Network.IpSpec (spec) where import HaskellWorks.Data.Network.Ip+import HaskellWorks.Data.Network.Ip.Internal import HaskellWorks.Hspec.Hedgehog import Hedgehog import Test.Hspec +import qualified Data.Attoparsec.Text as AP+import qualified Data.Text as T+import qualified Hedgehog.Gen as G+import qualified Hedgehog.Range as R+ {-# ANN module ("HLint: ignore Redundant do" :: String) #-} spec :: Spec spec = describe "HaskellWorks.HUnit.IpSpec" $ do+ describe "octet" $ do+ it "should go from 0-255" $ require $ property $ do+ b <- forAll $ G.word8 R.constantBounded+ AP.parseOnly octet (T.pack . show $ b) === Right b+ describe "Ipv4Address" $ do it "should implement show" $ require $ property $ do show (Ipv4Address 0x000000ff) === "0.0.0.255" show (Ipv4Address 0x0000ff00) === "0.0.255.0" show (Ipv4Address 0x00ff0000) === "0.255.0.0" show (Ipv4Address 0xff000000) === "255.0.0.0"+ it "should implement read" $ require $ property $ do read "1.2.3.4" === Ipv4Address 0x01020304 read "10.20.30.40" === Ipv4Address 0x0a141e28 read "1.2.3.12" === Ipv4Address 0x0102030c read "1.2.3.160" === Ipv4Address 0x010203a0+ describe "Ipv4Block" $ do it "should implement show" $ require $ property $ do show (Ipv4Block (Ipv4Address 0x000000ff) (Ipv4NetMask 32)) === "0.0.0.255/32"@@ -42,11 +55,18 @@ show (lastIpv4Address $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 32)) === "255.0.0.0" show (firstIpv4Address $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 21)) === "255.0.0.0" show (lastIpv4Address $ Ipv4Block (Ipv4Address 0xff000000) (Ipv4NetMask 21)) === "255.0.7.255"++ it "should implement read" $ require $ property $ do+ read "1.2.3.4/8" === Ipv4Block (Ipv4Address 0x01020304) (Ipv4NetMask 8)+ read "1.2.3.4/0" === Ipv4Block (Ipv4Address 0x01020304) (Ipv4NetMask 0)+ read "1.2.3.4/32" === Ipv4Block (Ipv4Address 0x01020304) (Ipv4NetMask 32)+ it "should implement splitBlock" $ require $ property $ do splitBlock (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 32)) === Nothing splitBlock (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 31)) === Just (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 32), Ipv4Block (Ipv4Address 0x00000001) (Ipv4NetMask 32)) splitBlock (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 30)) === Just (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 31), Ipv4Block (Ipv4Address 0x00000002) (Ipv4NetMask 31)) splitBlock (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 0)) === Just (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 1), Ipv4Block (Ipv4Address 0x80000000) (Ipv4NetMask 1))+ it "should implement blockSize" $ require $ property $ do blockSize (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 32)) === 1 blockSize (Ipv4Block (Ipv4Address 0x00000000) (Ipv4NetMask 0)) === 0x100000000