hw-ip 2.4.0.1 → 2.4.1.0
raw patch · 4 files changed
+87/−21 lines, 4 filesdep +doctestdep +doctest-discoverdep ~generic-lensPVP ok
version bump matches the API change (PVP)
Dependencies added: doctest, doctest-discover
Dependency ranges changed: generic-lens
API changes (from Hackage documentation)
+ HaskellWorks.Data.Network.Ip.Ipv6: isIpv4Block :: IpBlock v -> Bool
+ HaskellWorks.Data.Network.Ip.Ipv6: toIpv4Block :: IpBlock v -> Maybe (IpBlock v)
Files
- doctest/DoctestDriver.hs +12/−0
- hw-ip.cabal +40/−19
- src/HaskellWorks/Data/Network/Ip/Ipv6.hs +23/−2
- test/HaskellWorks/Data/Network/Ipv6Spec.hs +12/−0
+ doctest/DoctestDriver.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE CPP #-}++#if MIN_VERSION_GLASGOW_HASKELL(8,4,4,0)+{-# OPTIONS_GHC -F -pgmF doctest-discover #-}+#else+module Main where++import qualified System.IO as IO++main :: IO ()+main = IO.putStrLn "WARNING: doctest will not run on GHC versions earlier than 8.4.4"+#endif
hw-ip.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name: hw-ip-version: 2.4.0.1+version: 2.4.1.0 license: BSD-3-Clause license-file: LICENSE copyright: 2018-2019 John Ky, David Turnbull, Jian Wan@@ -22,28 +22,36 @@ type: git location: https://github.com/haskell-works/hw-ip -common base { build-depends: base >= 4 && < 5 }+common base { build-depends: base >= 4 && < 5 } -common appar { build-depends: appar >= 0.1.8 && < 0.2 }-common binary { build-depends: binary >= 0.8 && < 0.9 }-common bytestring { build-depends: bytestring >= 0.10.6 && < 0.11 }-common containers { build-depends: containers >= 0.5 && < 0.7 }-common generic-lens { build-depends: generic-lens >= 1.1.0.0 && < 1.3 }-common hedgehog { build-depends: hedgehog >= 0.6 && < 1.1 }-common hspec { build-depends: hspec >= 2.4.4 && < 2.8 }-common hw-bits { build-depends: hw-bits >= 0.7 && < 0.8 }-common hw-hspec-hedgehog { build-depends: hw-hspec-hedgehog >= 0.1.0.2 && < 0.2 }-common iproute { build-depends: iproute >= 1.7.3 && < 1.8 }-common lens { build-depends: lens >= 4 && < 5 }-common optparse-applicative { build-depends: optparse-applicative >= 0.14 && < 0.16 }-common text { build-depends: text >= 1.2.3.1 && < 1.3 }+common appar { build-depends: appar >= 0.1.8 && < 0.2 }+common binary { build-depends: binary >= 0.8 && < 0.9 }+common bytestring { build-depends: bytestring >= 0.10.6 && < 0.11 }+common containers { build-depends: containers >= 0.5 && < 0.7 }+common doctest { build-depends: doctest >= 0.16.2 && < 0.17 }+common doctest-discover { build-depends: doctest-discover >= 0.2 && < 0.3 }+common generic-lens { build-depends: generic-lens >= 1.1.0.0 && < 1.3 }+common hedgehog { build-depends: hedgehog >= 0.6 && < 1.1 }+common hspec { build-depends: hspec >= 2.4.4 && < 2.8 }+common hw-bits { build-depends: hw-bits >= 0.7 && < 0.8 }+common hw-hspec-hedgehog { build-depends: hw-hspec-hedgehog >= 0.1.0.2 && < 0.2 }+common iproute { build-depends: iproute >= 1.7.3 && < 1.8 }+common lens { build-depends: lens >= 4 && < 5 }+common optparse-applicative { build-depends: optparse-applicative >= 0.14 && < 0.16 }+common text { build-depends: text >= 1.2.3.1 && < 1.3 } -common semigroups { if impl(ghc < 8 ) { build-depends: semigroups >= 0.16 && < 0.19 } }+common semigroups { if impl(ghc < 8 ) { build-depends: semigroups >= 0.16 && < 0.19 } } common config default-language: Haskell2010 ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints +common hw-ip+ build-depends: hw-ip++common hw-ip-gen+ build-depends: hw-ip-gen+ library import: base, config , appar@@ -71,6 +79,7 @@ , binary , bytestring , generic-lens+ , hw-ip , lens , optparse-applicative , semigroups@@ -82,16 +91,15 @@ main-is: Main.hs hs-source-dirs: app ghc-options: -threaded -rtsopts -with-rtsopts=-N- build-depends: hw-ip library hw-ip-gen import: base, config , hedgehog , hw-bits+ , hw-ip , text exposed-modules: HaskellWorks.Data.Network.Gen hs-source-dirs: gen- build-depends: hw-ip test-suite hw-ip-test import: base, config@@ -101,6 +109,8 @@ , hspec , hw-bits , hw-hspec-hedgehog+ , hw-ip+ , hw-ip-gen , text other-modules: HaskellWorks.Data.Network.IpBlockSpec HaskellWorks.Data.Network.IpSpec@@ -112,5 +122,16 @@ main-is: Spec.hs hs-source-dirs: test ghc-options: -threaded -rtsopts -with-rtsopts=-N- build-depends: hw-ip, hw-ip-gen build-tool-depends: hspec-discover:hspec-discover++test-suite doctest+ import: base, config+ , doctest+ , doctest-discover+ , hw-ip+ default-language: Haskell2010+ type: exitcode-stdio-1.0+ ghc-options: -threaded+ main-is: DoctestDriver.hs+ HS-Source-Dirs: doctest+ build-tool-depends: doctest-discover:doctest-discover
src/HaskellWorks/Data/Network/Ip/Ipv6.hs view
@@ -13,6 +13,8 @@ , Unaligned, Canonical , fromIpv4 , fromIpv4Block+ , isIpv4Block+ , toIpv4Block , fromV4 , parseIpBlock , masksIp@@ -48,6 +50,7 @@ import qualified HaskellWorks.Data.Network.Ip.Internal.Appar as I import qualified HaskellWorks.Data.Network.Ip.Ipv4 as V4 import qualified HaskellWorks.Data.Network.Ip.Word128 as W+import qualified Text.Appar.String as AP newtype IpAddress = IpAddress W.Word128 deriving (Enum, Eq, Ord, Bounded, Generic, SafeEnum) @@ -56,11 +59,17 @@ instance Read IpAddress where readsPrec :: Int -> String -> [(IpAddress, String)]- readsPrec _ s =+ readsPrec p s = case readMaybe s :: Maybe D.IPv6 of Just ip -> [(IpAddress (D.toHostAddress6 ip), "")]- Nothing -> []+ Nothing -> I.readsPrecOnParser (AP.try parse6052IpAddress) p s +-- Data.IP doesn't support this encoding, so we have to do it ourselves. It's pretty unambiguous.+parse6052IpAddress :: AP.Parser IpAddress+parse6052IpAddress = do+ _ <- AP.string "::ffff:"+ fromIpv4 <$> V4.parseIpAddress+ newtype IpNetMask = IpNetMask { word :: Word8 } deriving (Enum, Eq, Ord, Show, Generic)@@ -165,6 +174,18 @@ fromIpv4 :: V4.IpAddress -> IpAddress fromIpv4 (V4.IpAddress w32) = IpAddress (0, 0, 0xFFFF, w32)++isIpv4Block :: IpBlock v -> Bool+isIpv4Block (IpBlock (IpAddress (a, b, c, _)) _) = a == 0 && b == 0 && c == 0xffff++toIpv4Block :: IpBlock v -> Maybe (V4.IpBlock v)+toIpv4Block b@(IpBlock (IpAddress (_, _, _, d)) (IpNetMask m))+ | isIpv4Block b =+ let v4Addr = V4.IpAddress d+ v4Mask = V4.IpNetMask (m - 96)+ in pure $ V4.IpBlock v4Addr v4Mask+ | otherwise = Nothing+ canonicaliseIpBlock :: IpBlock v -> IpBlock Canonical canonicaliseIpBlock (IpBlock (IpAddress w) (IpNetMask m))
test/HaskellWorks/Data/Network/Ipv6Spec.hs view
@@ -113,3 +113,15 @@ it "::100 - ::200" $ requireTest $ do V6.rangeToBlocksDL (R.Range (V6.IpAddress 0x100) (V6.IpAddress 0x200)) [] === [ V6.IpBlock (V6.IpAddress 0x100) (V6.IpNetMask 120) , V6.IpBlock (V6.IpAddress 0x200) (V6.IpNetMask 128)]++ describe "should handle 4-in-6 encoding" $ do+ it "::ffff:10.43.52.11/128" $ requireTest $ do+ read "::ffff:10.43.52.11/128" === V6.IpBlock @Unaligned (V6.IpAddress (0,0,0xffff,0x0a2b340b)) (V6.IpNetMask 128)++ describe "should be able to detect 4-in-6 encoded addresses" $ do+ it "::ffff:10.43.52.11/128" $ requireTest $ do+ V6.isIpv4Block (read "::ffff:10.43.52.11/128" :: V6.IpBlock Unaligned) === True++ describe "should be able to convert 4-in-6 encoded addresses to ipv4" $ do+ it "::ffff:10.43.52.11/128" $ requireTest $ do+ V6.toIpv4Block (read "::ffff:10.43.52.11/128") === Just (V4.IpBlock @Unaligned (V4.IpAddress 0x0a2b340b) (V4.IpNetMask 32))