packages feed

ip 1.5.0 → 1.5.1

raw patch · 3 files changed

+95/−27 lines, 3 filesdep ~hashablePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: hashable

API changes (from Hackage documentation)

+ Net.IP: isIPv4 :: IP -> Bool
+ Net.IP: isIPv6 :: IP -> Bool

Files

ip.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.0 name: ip-version: 1.5.0+version: 1.5.1 synopsis: Library for IP and MAC addresses homepage: https://github.com/andrewthad/haskell-ip#readme license: BSD3@@ -50,9 +50,9 @@     , aeson >= 1.0 && < 1.5     , attoparsec >= 0.13 && < 0.14     , bytestring >= 0.10 && < 0.11-    , deepseq >= 1.4 && < 1.5 -    , hashable >= 1.2 && < 1.3-    , primitive >= 0.6 && < 0.7+    , deepseq >= 1.4 && < 1.5+    , hashable >= 1.2 && < 1.4+    , primitive >= 0.6.4 && < 0.8     , text >= 1.2  && < 1.3     , vector >= 0.11 && < 0.13     , wide-word >= 0.1.0.8 && < 0.2
src/Net/IP.hs view
@@ -17,9 +17,9 @@     All functions and instance methods that deal with textual conversion     will encode an 'IP' using either dot-decimal notation (for IPv4) or     RFC 5952 (for IPv6). They will decode an 'IP' from either format-    as well. The 'Show' instance presents an address in as valid haskell code +    as well. The 'Show' instance presents an address in as valid haskell code     that resembles the formatted address:-    +     >>> decode "192.168.3.100"     Just (ipv4 192 168 3 100)     >>> decode "A3F5:12:F26::1466:8B91"@@ -29,6 +29,8 @@ module Net.IP   ( -- * Pattern Matching     case_+  , isIPv4+  , isIPv6     -- * Construction   , ipv4   , ipv6@@ -44,23 +46,26 @@   , IP(..)   ) where -import Prelude hiding (print) import Control.DeepSeq (NFData)-import Data.Bits-import GHC.Generics (Generic)-import Net.IPv6 (IPv6(..))-import Net.IPv4 (IPv4(..))-import Text.Read (Read(..))-import Text.ParserCombinators.ReadPrec ((+++)) import Data.Aeson (FromJSON(..),ToJSON(..))+import Data.Bits import Data.Text (Text) import Data.WideWord (Word128(..)) import Data.Word (Word8,Word16)-import qualified Net.IPv4 as IPv4-import qualified Net.IPv6 as IPv6+import GHC.Generics (Generic)+import Net.IPv4 (IPv4(..))+import Net.IPv6 (IPv6(..))+import Prelude hiding (print)+import Text.ParserCombinators.ReadPrec ((+++))+import Text.Read (Read(..)) import qualified Data.Aeson as Aeson import qualified Data.Text.IO as TIO+import qualified Net.IPv4 as IPv4+import qualified Net.IPv6 as IPv6 +-- $setup+-- >>> :set -XOverloadedStrings+ -- | Run a function over an 'IP' depending on its status --   as an 'IPv4' or 'IPv6'. --@@ -99,10 +104,28 @@ fromIPv6 = IP  -- | Encode an 'IP' as 'Text'.+--+--   >>> encode (ipv4 10 0 0 25)+--   "10.0.0.25"+--+--   >>> encode (ipv6 0x3124 0x0 0x0 0xDEAD 0xCAFE 0xFF 0xFE00 0x1)+--   "3124::dead:cafe:ff:fe00:1" encode :: IP -> Text encode = case_ IPv4.encode IPv6.encode  -- | Decode an 'IP' from 'Text'.+--+--   >>> decode "10.0.0.25"+--   Just (ipv4 10 0 0 25)+--+--   >>> fmap isIPv4 (decode "10.0.0.25")+--   Just True+--+--   >>> decode "3124::dead:cafe:ff:fe00:1"+--   Just (ipv6 0x3124 0x0000 0x0000 0xdead 0xcafe 0x00ff 0xfe00 0x0001)+--+--   >>> fmap isIPv6 (decode "3124::dead:cafe:ff:fe00:1")+--   Just True decode :: Text -> Maybe IP decode t = case IPv4.decode t of   Nothing -> case IPv6.decode t of@@ -110,7 +133,36 @@     Just v6 -> Just (fromIPv6 v6)   Just v4 -> Just (fromIPv4 v4) --- | Print an 'IP' using the textual encoding.+-- | Is the 'IP' an IPv4 address?+--+--   >>> isIPv4 (ipv4 10 0 0 25)+--   True+--+--   >>> isIPv4 (ipv6 0x3124 0x0 0x0 0xDEAD 0xCAFE 0xFF 0xFE00 0x1)+--   False+isIPv4 :: IP -> Bool+isIPv4 = case_ (const True) (const False)+{-# inline isIPv4 #-}++-- | Is the 'IP' an IPv6 address?+--+--   >>> isIPv6 (ipv4 10 0 0 25)+--   False+--+--   >>> isIPv6 (ipv6 0x3124 0x0 0x0 0xDEAD 0xCAFE 0xFF 0xFE00 0x1)+--   True+isIPv6 :: IP -> Bool+isIPv6 = case_ (const False) (const True)+{-# inline isIPv6 #-}++-- | Print an 'IP' using the textual encoding. This exists mostly for+--   debugging purposes.+--+--   >>> print (ipv4 10 0 0 25)+--   10.0.0.25+--+--   >>> print (ipv6 0x3124 0x0 0x0 0xDEAD 0xCAFE 0xFF 0xFE00 0x1)+--   3124::dead:cafe:ff:fe00:1 print :: IP -> IO () print = TIO.putStrLn . encode 
src/Net/IPv4.hs view
@@ -122,6 +122,7 @@ -- -- These are here to get doctest's property checking to work --+-- >>> :set -XOverloadedStrings -- >>> import Test.QuickCheck (Arbitrary(..)) -- >>> import qualified Prelude as P -- >>> import qualified Data.Text.IO as T@@ -262,10 +263,10 @@  -- | Decode an 'IPv4' address. -----   >>> decode (Text.pack "192.168.2.47")+--   >>> decode "192.168.2.47" --   Just (ipv4 192 168 2 47) -----   >>> decode (Text.pack "10.100.256.256")+--   >>> decode "10.100.256.256" --   Nothing decode :: Text -> Maybe IPv4 decode = decodeIPv4TextMaybe@@ -279,20 +280,20 @@  -- | Parse an 'IPv4' address using a 'TextRead.Reader'. -----   >>> reader (Text.pack "192.168.2.47")+--   >>> reader "192.168.2.47" --   Right (ipv4 192 168 2 47,"") -----   >>> reader (Text.pack "192.168.2.470")+--   >>> reader "192.168.2.470" --   Left "All octets in an IPv4 address must be between 0 and 255" reader :: TextRead.Reader IPv4 reader = decodeIPv4TextReader  -- | Parse an 'IPv4' address using a 'AT.Parser'. -----   >>> AT.parseOnly parser (Text.pack "192.168.2.47")+--   >>> AT.parseOnly parser "192.168.2.47" --   Right (ipv4 192 168 2 47) -----   >>> AT.parseOnly parser (Text.pack "192.168.2.470")+--   >>> AT.parseOnly parser "192.168.2.470" --   Left "Failed reading: All octets in an IPv4 address must be between 0 and 255" parser :: AT.Parser IPv4 parser = dotDecimalParser@@ -345,7 +346,7 @@  -- | Decode a UTF8-encoded 'ByteString' into an 'IPv4'. -----   >>> decodeUtf8 (BC8.pack "192.168.2.47")+--   >>> decodeUtf8 "192.168.2.47" --   Just (ipv4 192 168 2 47) decodeUtf8 :: ByteString -> Maybe IPv4 decodeUtf8 = decode <=< rightToMaybe . decodeUtf8'@@ -358,10 +359,10 @@  -- | Parse an 'IPv4' using a 'AB.Parser'. -----   >>> AB.parseOnly parserUtf8 (BC8.pack "192.168.2.47")+--   >>> AB.parseOnly parserUtf8 "192.168.2.47" --   Right (ipv4 192 168 2 47) -----   >>> AB.parseOnly parserUtf8 (BC8.pack "192.168.2.470")+--   >>> AB.parseOnly parserUtf8 "192.168.2.470" --   Left "Failed reading: All octets in an ipv4 address must be between 0 and 255" parserUtf8 :: AB.Parser IPv4 parserUtf8 = fromOctets'@@ -882,18 +883,32 @@    in IPv4Range (IPv4 w') len'  -- | Encode an 'IPv4Range' as 'Text'.+--+--   >>> encodeRange (IPv4Range (ipv4 172 16 0 0) 12)+--   "172.16.0.0/12" encodeRange :: IPv4Range -> Text encodeRange = rangeToDotDecimalText  -- | Decode an 'IPv4Range' from 'Text'.+--+--   >>> decodeRange "172.16.0.0/12"+--   Just (IPv4Range {ipv4RangeBase = ipv4 172 16 0 0, ipv4RangeLength = 12})+--   >>> decodeRange "192.168.25.254/16"+--   Just (IPv4Range {ipv4RangeBase = ipv4 192 168 0 0, ipv4RangeLength = 16}) decodeRange :: Text -> Maybe IPv4Range decodeRange = rightToMaybe . AT.parseOnly (parserRange <* AT.endOfInput)  -- | Encode an 'IPv4Range' to a 'TBuilder.Builder'.+--+--   >>> builderRange (IPv4Range (ipv4 172 16 0 0) 12)+--   "172.16.0.0/12" builderRange :: IPv4Range -> TBuilder.Builder builderRange = rangeToDotDecimalBuilder --- | Parse an 'IPv4Range' using a 'AT.Parser.'+-- | Parse an 'IPv4Range' using a 'AT.Parser'.+--+--   >>> AT.parseOnly parserRange "192.168.25.254/16"+--   Right (IPv4Range {ipv4RangeBase = ipv4 192 168 0 0, ipv4RangeLength = 16}) parserRange :: AT.Parser IPv4Range parserRange = do   ip <- parser@@ -906,7 +921,8 @@       then fail "An IP range length must be between 0 and 32"       else return i --- | This exists mostly for testing purposes.+-- | Print an 'IPv4Range'. Helper function that+--   exists mostly for testing purposes. printRange :: IPv4Range -> IO () printRange = TIO.putStrLn . encodeRange