packages feed

multiaddr 0.2.0 → 0.3.0

raw patch · 3 files changed

+184/−172 lines, 3 filesdep ~multiaddr

Dependency ranges changed: multiaddr

Files

multiaddr.cabal view
@@ -1,5 +1,5 @@ name: multiaddr-version: 0.2.0+version: 0.3.0 cabal-version: >=1.10 build-type: Simple license: BSD3@@ -44,7 +44,7 @@     main-is: test.hs     build-depends:         base >=4.7 && <5,-        multiaddr >=0.2.0 && <0.3,+        multiaddr >=0.3.0 && <0.4,         tasty >=0.11.0.2 && <0.12,         tasty-hunit >=0.9.2 && <0.10,         tasty-quickcheck >=0.8.4 && <0.9,
src/Network/Multiaddr.hs view
@@ -32,21 +32,23 @@        , hasIPv6        , hasUDP        , hasTCP+       , hasUDT+       , hasUTP        , hasDCCP        , hasSCTP        , hasIPFS -         -- * AddrPart type-       , AddrPart(..)+         -- * MultiaddrPart type+       , MultiaddrPart(..)           -- * IPv4 type-       , IPv4(..)-       , readIPv4+       , IPv4Addr(..)+       , readIPv4Addr        , fromBytes           -- * IPv6 type-       , IPv6(..)-       , readIPv6+       , IPv6Addr(..)+       , readIPv6Addr        , fromPieces        ) where @@ -80,35 +82,35 @@ import           Data.Serialize.Varint  -- | An IPv4 address.-data IPv4 = IPv4 {-# UNPACK #-} !Word32+data IPv4Addr = IPv4Addr {-# UNPACK #-} !Word32           deriving (Eq, Ord, Bounded, Generic, Typeable) -instance Hashable IPv4+instance Hashable IPv4Addr -instance Serialize IPv4 where-  get = IPv4 <$> get-  put (IPv4 w) = put w+instance Serialize IPv4Addr where+  get = IPv4Addr <$> get+  put (IPv4Addr w) = put w  -- | An IPv6 address.-data IPv6 = IPv6+data IPv6Addr = IPv6Addr             {-# UNPACK #-} !Word32             {-# UNPACK #-} !Word32             {-# UNPACK #-} !Word32             {-# UNPACK #-} !Word32           deriving (Eq, Ord, Bounded, Generic, Typeable) -instance Hashable IPv6+instance Hashable IPv6Addr -instance Serialize IPv6 where-  get = IPv6 <$> get <*> get <*> get <*> get-  put (IPv6 a b c d) = put a >> put b >> put c >> put d+instance Serialize IPv6Addr where+  get = IPv6Addr <$> get <*> get <*> get <*> get+  put (IPv6Addr a b c d) = put a >> put b >> put c >> put d -asBytes :: IPv4 -> [Word8]-asBytes (IPv4 ip) =+asBytes :: IPv4Addr -> [Word8]+asBytes (IPv4Addr ip) =   map (\n -> fromIntegral (ip `shiftR` n) .&. 0xFF) [24, 16, 8, 0] -asPieces :: IPv6 -> [Word16]-asPieces (IPv6 a b c d) =+asPieces :: IPv6Addr -> [Word16]+asPieces (IPv6Addr a b c d) =   map fromIntegral [ a `shiftR` 16                    , a .&. 0xFFFF                    , b `shiftR` 16@@ -119,16 +121,16 @@                    , d .&. 0xFFFF                    ] -fromBytes :: (Word8, Word8, Word8, Word8) -> IPv4-fromBytes (a, b, c, d) = IPv4 ( shiftL (fromIntegral a) 24-                          `xor` shiftL (fromIntegral b) 16-                          `xor` shiftL (fromIntegral c) 8-                          `xor` fromIntegral d)+fromBytes :: (Word8, Word8, Word8, Word8) -> IPv4Addr+fromBytes (a, b, c, d) = IPv4Addr ( shiftL (fromIntegral a) 24+                                    `xor` shiftL (fromIntegral b) 16+                                    `xor` shiftL (fromIntegral c) 8+                                    `xor` fromIntegral d)  fromPieces :: (Word16, Word16, Word16, Word16, Word16, Word16, Word16, Word16)-               -> IPv6+               -> IPv6Addr fromPieces (a, b, c, d, e, f, g, h) =-    IPv6 (word a b) (word c d) (word e f) (word g h)+    IPv6Addr (word a b) (word c d) (word e f) (word g h)   where word x y = (fromIntegral x `shiftL` 16) `xor` fromIntegral y  word8P :: Parser Word8@@ -137,8 +139,8 @@   guard (w >= 0 && w <= 255)   pure (fromIntegral w) -ipv4P :: Parser IPv4-ipv4P = do+ipv4AddrP :: Parser IPv4Addr+ipv4AddrP = do   a <- word8P <* char '.'   b <- word8P <* char '.'   c <- word8P <* char '.'@@ -146,8 +148,8 @@   pure (fromBytes (a, b, c, d))  -- | Try to read an IPv4 address (e.g. @"192.168.1.2"@)-readIPv4 :: Text -> Maybe IPv4-readIPv4 = hush . parseOnly (ipv4P <* endOfInput)+readIPv4Addr :: Text -> Maybe IPv4Addr+readIPv4Addr = hush . parseOnly (ipv4AddrP <* endOfInput)  word16P :: Parser Word16 word16P = do@@ -155,8 +157,8 @@   guard (w >= 0 && w <= 65535)   pure (fromIntegral w) -ipv6P :: Parser IPv6-ipv6P = do+ipv6AddrP :: Parser IPv6Addr+ipv6AddrP = do     heads <- sepBy' word16P (char ':')     _ <- option ':' (char ':' *> char ':')     tails <- sepBy' word16P (char ':')@@ -170,18 +172,19 @@  -- | Try to read an IPv6 address -- (e.g. @"2001:db8:85a3:8d3:1319:8a2e:370:7348"@)-readIPv6 :: Text -> Maybe IPv6-readIPv6 = hush . parseOnly (ipv6P <* endOfInput)+readIPv6Addr :: Text -> Maybe IPv6Addr+readIPv6Addr = hush . parseOnly (ipv6AddrP <* endOfInput) -ipv4B :: IPv4 -> Builder-ipv4B = mconcat . intersperse (singleton '.') . map Builder.decimal . asBytes+ipv4AddrB :: IPv4Addr -> Builder+ipv4AddrB =+  mconcat . intersperse (singleton '.') . map Builder.decimal . asBytes  {- All we need for ipv6B to pass LiquidHaskell -} {-@ assert scanl' :: (b -> a -> b) -> b -> xs:[a]                      -> {v : [b] | len(v) = 1 + len(xs) } @-} -ipv6B :: IPv6 -> Builder-ipv6B ip =+ipv6AddrB :: IPv6Addr -> Builder+ipv6AddrB ip =   if maxRun <= 1      then trans pieces      else trans start <> fromText "::" <> trans end@@ -197,76 +200,76 @@ class TextAddr a where   toText :: a -> Text -instance TextAddr IPv4 where-  toText = toStrict . toLazyText . ipv4B+instance TextAddr IPv4Addr where+  toText = toStrict . toLazyText . ipv4AddrB  -- | RFC 5952 Compliant-instance TextAddr IPv6 where-  toText = toStrict . toLazyText . ipv6B+instance TextAddr IPv6Addr where+  toText = toStrict . toLazyText . ipv6AddrB -instance Show IPv4 where+instance Show IPv4Addr where   show = T.unpack . toText -instance Show IPv6 where+instance Show IPv6Addr where   show = T.unpack . toText  -- | An individual component of a multiaddr.-data AddrPart = IPv4Part !IPv4-              | IPv6Part !IPv6-              | UDPPart !Word16-              | TCPPart !Word16-              | DCCPPart !Word16-              | SCTPPart !Word16-              | IPFSPart !ByteString-              | UDTPart-              | UTPPart-              | HTTPPart-              | HTTPSPart+data MultiaddrPart = IPv4 !IPv4Addr+              | IPv6 !IPv6Addr+              | UDP !Word16+              | TCP !Word16+              | DCCP !Word16+              | SCTP !Word16+              | IPFS !ByteString+              | UDT+              | UTP+              | HTTP+              | HTTPS               deriving (Eq, Generic, Typeable) -instance Hashable AddrPart+instance Hashable MultiaddrPart -instance Serialize AddrPart where-  put (IPv4Part ip) = put (4 :: Varint Word32) >> put ip-  put (IPv6Part ip) = put (41 :: Varint Word32) >> put ip-  put (UDPPart port) = put (17 :: Varint Word32) >> put port-  put (TCPPart port) = put (6 :: Varint Word32) >> put port-  put (DCCPPart port) = put (33 :: Varint Word32) >> put port-  put (SCTPPart port) = put (132 :: Varint Word32) >> put port-  put (IPFSPart addr) = do+instance Serialize MultiaddrPart where+  put (IPv4 ip) = put (4 :: Varint Word32) >> put ip+  put (IPv6 ip) = put (41 :: Varint Word32) >> put ip+  put (UDP port) = put (17 :: Varint Word32) >> put port+  put (TCP port) = put (6 :: Varint Word32) >> put port+  put (DCCP port) = put (33 :: Varint Word32) >> put port+  put (SCTP port) = put (132 :: Varint Word32) >> put port+  put (IPFS addr) = do     put (421 :: Varint Word32)     case decodeBase58 bitcoinAlphabet addr of       Nothing -> fail "invalid base58"       Just bytes -> do         put (fromIntegral (BS.length bytes) :: Varint Word64)         mapM_ put (BS.unpack bytes)-  put UDTPart = put (301 :: Varint Word32)-  put UTPPart = put (302 :: Varint Word32)-  put HTTPPart = put (480 :: Varint Word32)-  put HTTPSPart = put (443 :: Varint Word32)+  put UDT = put (301 :: Varint Word32)+  put UTP = put (302 :: Varint Word32)+  put HTTP = put (480 :: Varint Word32)+  put HTTPS = put (443 :: Varint Word32)    get = do     code <- get :: Get (Varint Word32)     case code of-      4 -> IPv4Part <$> get-      6 -> TCPPart <$> get-      17 -> UDPPart <$> get-      33 -> DCCPPart <$> get-      41 -> IPv6Part <$> get-      132 -> SCTPPart <$> get+      4 -> IPv4 <$> get+      6 -> TCP <$> get+      17 -> UDP <$> get+      33 -> DCCP <$> get+      41 -> IPv6 <$> get+      132 -> SCTP <$> get       421 -> do         len <- get :: Get (Varint Word64)         bytes <- getBytes (fromIntegral len)         let base58 = encodeBase58 bitcoinAlphabet bytes-        pure (IPFSPart base58)-      301 -> pure UDTPart-      302 -> pure UTPPart-      480 -> pure HTTPPart-      443 -> pure HTTPSPart+        pure (IPFS base58)+      301 -> pure UDT+      302 -> pure UTP+      480 -> pure HTTP+      443 -> pure HTTPS       _ -> fail "invalid multiaddr code"  -- | A network address.-newtype Multiaddr = Multiaddr { _parts :: [AddrPart] }+newtype Multiaddr = Multiaddr { _parts :: [MultiaddrPart] }                   deriving (Eq, Monoid, Generic, Typeable)  instance Hashable Multiaddr@@ -278,75 +281,75 @@  -- | Get the individual parts of the multiaddr, in order -- (e.g. @["\/ip4\/8.8.8.8", "\/tcp\/80"]@)-parts :: Multiaddr -> [AddrPart]+parts :: Multiaddr -> [MultiaddrPart] parts = _parts -ipv4PartP :: Parser AddrPart-ipv4PartP = IPv4Part <$> (string "/ip4/" *> ipv4P)+ipv4PartP :: Parser MultiaddrPart+ipv4PartP = IPv4 <$> (string "/ip4/" *> ipv4AddrP) -ipv6PartP :: Parser AddrPart-ipv6PartP = IPv6Part <$> (string "/ip6/" *> ipv6P)+ipv6PartP :: Parser MultiaddrPart+ipv6PartP = IPv6 <$> (string "/ip6/" *> ipv6AddrP) -udpPartP :: Parser AddrPart+udpPartP :: Parser MultiaddrPart udpPartP = do   _ <- string "/udp/"   port <- decimal :: Parser Integer   guard (port >= 0 && port <= 65535)-  pure (UDPPart (fromIntegral port))+  pure (UDP (fromIntegral port)) -dccpPartP :: Parser AddrPart+dccpPartP :: Parser MultiaddrPart dccpPartP = do   _ <- string "/dccp/"   port <- decimal :: Parser Integer   guard (port >= 0 && port <= 65535)-  pure (DCCPPart (fromIntegral port))+  pure (DCCP (fromIntegral port)) -sctpPartP :: Parser AddrPart+sctpPartP :: Parser MultiaddrPart sctpPartP = do   _ <- string "/sctp/"   port <- decimal :: Parser Integer   guard (port >= 0 && port <= 65535)-  pure (SCTPPart (fromIntegral port))+  pure (SCTP (fromIntegral port)) -udtPartP :: Parser AddrPart-udtPartP = string "/udt" >> pure UDTPart+udtPartP :: Parser MultiaddrPart+udtPartP = string "/udt" >> pure UDT -utpPartP :: Parser AddrPart-utpPartP = string "/utp" >> pure UTPPart+utpPartP :: Parser MultiaddrPart+utpPartP = string "/utp" >> pure UTP -httpPartP :: Parser AddrPart-httpPartP = string "/http" >> pure HTTPPart+httpPartP :: Parser MultiaddrPart+httpPartP = string "/http" >> pure HTTP -httpsPartP :: Parser AddrPart-httpsPartP = string "/https" >> pure HTTPSPart+httpsPartP :: Parser MultiaddrPart+httpsPartP = string "/https" >> pure HTTPS -tcpPartP :: Parser AddrPart+tcpPartP :: Parser MultiaddrPart tcpPartP = do   _ <- string "/tcp/"   port <- decimal :: Parser Integer   guard (port >= 0 && port <= 65535)-  pure (TCPPart (fromIntegral port))+  pure (TCP (fromIntegral port)) -ipfsPartP :: Parser AddrPart+ipfsPartP :: Parser MultiaddrPart ipfsPartP = do   _ <- string "/ipfs/"   addr <- takeTill (== '/')-  pure (IPFSPart (T.encodeUtf8 addr))+  pure (IPFS (T.encodeUtf8 addr))  multiaddrP :: Parser Multiaddr multiaddrP = do   _parts <- many' (choice [ ipv4PartP-                         , ipv6PartP-                         , ipfsPartP-                         , udpPartP-                         , tcpPartP-                         , dccpPartP-                         , sctpPartP-                         , udtPartP-                         , utpPartP-                         , httpPartP-                         , httpsPartP-                         ])+                          , ipv6PartP+                          , ipfsPartP+                          , udpPartP+                          , tcpPartP+                          , dccpPartP+                          , sctpPartP+                          , udtPartP+                          , utpPartP+                          , httpPartP+                          , httpsPartP+                          ])   pure Multiaddr{..}  -- | Try to read a multiaddr in the standard text format@@ -354,23 +357,23 @@ readMultiaddr :: Text -> Maybe Multiaddr readMultiaddr = hush . parseOnly (multiaddrP <* endOfInput) -addrPartB :: AddrPart -> Builder-addrPartB (IPv4Part ip) = fromText "/ip4/" <> ipv4B ip-addrPartB (IPv6Part ip) = fromText "/ip6/" <> ipv6B ip-addrPartB (UDPPart port) = fromText "/udp/" <> Builder.decimal port-addrPartB (TCPPart port) = fromText "/tcp/" <> Builder.decimal port-addrPartB (DCCPPart port) = fromText "/dccp/" <> Builder.decimal port-addrPartB (SCTPPart port) = fromText "/sctp/" <> Builder.decimal port-addrPartB (IPFSPart addr) = fromText "/ipfs/" <> fromText (T.decodeUtf8 addr)-addrPartB UDTPart = fromText "/udt"-addrPartB UTPPart = fromText "/utp"-addrPartB HTTPPart = fromText "/http"-addrPartB HTTPSPart = fromText "/https"+addrPartB :: MultiaddrPart -> Builder+addrPartB (IPv4 ip) = fromText "/ip4/" <> ipv4AddrB ip+addrPartB (IPv6 ip) = fromText "/ip6/" <> ipv6AddrB ip+addrPartB (UDP port) = fromText "/udp/" <> Builder.decimal port+addrPartB (TCP port) = fromText "/tcp/" <> Builder.decimal port+addrPartB (DCCP port) = fromText "/dccp/" <> Builder.decimal port+addrPartB (SCTP port) = fromText "/sctp/" <> Builder.decimal port+addrPartB (IPFS addr) = fromText "/ipfs/" <> fromText (T.decodeUtf8 addr)+addrPartB UDT = fromText "/udt"+addrPartB UTP = fromText "/utp"+addrPartB HTTP = fromText "/http"+addrPartB HTTPS = fromText "/https" -instance TextAddr AddrPart where+instance TextAddr MultiaddrPart where   toText = toStrict . toLazyText . addrPartB -instance Show AddrPart where+instance Show MultiaddrPart where   show = T.unpack . toText  multiaddrB :: Multiaddr -> Builder@@ -392,31 +395,39 @@  -- | Does the multiaddr contain an IPv4 part? hasIPv4 :: Multiaddr -> Bool-hasIPv4 (Multiaddr ps) = any (\case IPv4Part _ -> True; _ -> False) ps+hasIPv4 (Multiaddr ps) = any (\case IPv4 _ -> True; _ -> False) ps  -- | Does the multiaddr contain an IPv6 part? hasIPv6 :: Multiaddr -> Bool-hasIPv6 (Multiaddr ps) = any (\case IPv6Part _ -> True; _ -> False) ps+hasIPv6 (Multiaddr ps) = any (\case IPv6 _ -> True; _ -> False) ps  -- | Does the multiaddr contain a TCP part? hasTCP :: Multiaddr -> Bool-hasTCP (Multiaddr ps) = any (\case TCPPart _ -> True; _ -> False) ps+hasTCP (Multiaddr ps) = any (\case TCP _ -> True; _ -> False) ps  -- | Does the multiaddr contain a UDP part? hasUDP :: Multiaddr -> Bool-hasUDP (Multiaddr ps) = any (\case UDPPart _ -> True; _ -> False) ps+hasUDP (Multiaddr ps) = any (\case UDP _ -> True; _ -> False) ps +-- | Does the multiaddr contain a UDT part?+hasUDT :: Multiaddr -> Bool+hasUDT (Multiaddr ps) = any (== UDT) ps++-- | Does the multiaddr contain a UTP part?+hasUTP :: Multiaddr -> Bool+hasUTP (Multiaddr ps) = any (== UTP) ps+ -- | Does the multiaddr contain a DCCP part? hasDCCP :: Multiaddr -> Bool-hasDCCP (Multiaddr ps) = any (\case DCCPPart _ -> True; _ -> False) ps+hasDCCP (Multiaddr ps) = any (\case DCCP _ -> True; _ -> False) ps  -- | Does the multiaddr contain an SCTP part? hasSCTP :: Multiaddr -> Bool-hasSCTP (Multiaddr ps) = any (\case SCTPPart _ -> True; _ -> False) ps+hasSCTP (Multiaddr ps) = any (\case SCTP _ -> True; _ -> False) ps  -- | Does the multiaddr contain an IPFS part? hasIPFS :: Multiaddr -> Bool-hasIPFS (Multiaddr ps) = any (\case IPFSPart _ -> True; _ -> False) ps+hasIPFS (Multiaddr ps) = any (\case IPFS _ -> True; _ -> False) ps  -- | Append two multiaddrs (alias for @(<>)@) encapsulate :: Multiaddr -> Multiaddr -> Multiaddr@@ -426,14 +437,14 @@ -- Protocols can appear more than once if they are repeated in the multiaddr. protocolNames :: Multiaddr -> [Text] protocolNames (Multiaddr ms) = map protoName ms-  where protoName (IPv4Part _) = "ip4"-        protoName (IPv6Part _) = "ip6"-        protoName (UDPPart _) = "udp"-        protoName (TCPPart _) = "tcp"-        protoName (DCCPPart _) = "dccp"-        protoName (SCTPPart _) = "sctp"-        protoName (IPFSPart _) = "ipfs"-        protoName UDTPart = "udt"-        protoName UTPPart = "utp"-        protoName HTTPPart = "http"-        protoName HTTPSPart = "https"+  where protoName (IPv4 _) = "ip4"+        protoName (IPv6 _) = "ip6"+        protoName (UDP _) = "udp"+        protoName (TCP _) = "tcp"+        protoName (DCCP _) = "dccp"+        protoName (SCTP _) = "sctp"+        protoName (IPFS _) = "ipfs"+        protoName UDT = "udt"+        protoName UTP = "utp"+        protoName HTTP = "http"+        protoName HTTPS = "https"
test/test.hs view
@@ -8,10 +8,10 @@  import           Network.Multiaddr -instance QC.Arbitrary IPv4 where+instance QC.Arbitrary IPv4Addr where   arbitrary = fromBytes <$> QC.arbitrary -instance QC.Arbitrary IPv6 where+instance QC.Arbitrary IPv6Addr where   arbitrary = do     (a, b, c, d) <- QC.arbitrary     (e, f, g, h) <- QC.arbitrary@@ -20,10 +20,10 @@ ipv4Tests :: TestTree ipv4Tests = testGroup "IPv4"   [ QC.testProperty "round trips" $-    \ipv4 -> readIPv4 (toText (ipv4 :: IPv4)) == Just ipv4+    \ipv4 -> readIPv4Addr (toText (ipv4 :: IPv4Addr)) == Just ipv4    , testCase "parses and formats sample IPs" $-    mapM_ (\t -> toText (fromJust (readIPv4 t)) @?= t)+    mapM_ (\t -> toText (fromJust (readIPv4Addr t)) @?= t)     [ "0.0.0.0"     , "0.0.0.1"     , "1.1.1.1"@@ -33,7 +33,7 @@     , "255.255.255.255"     ] -  , testCase "fails to parse bad IPs" $ mapM_ (\t -> readIPv4 t @?= Nothing)+  , testCase "fails to parse bad IPs" $ mapM_ (\t -> readIPv4Addr t @?= Nothing)     [ ""     , "foo"     , "..."@@ -46,28 +46,28 @@     ]    , testCase "Bounded instance" $ do-      (minBound :: IPv4) @?= IPv4 0-      (maxBound :: IPv4) @?= IPv4 0xFFFFFFFF+      (minBound :: IPv4Addr) @?= IPv4Addr 0+      (maxBound :: IPv4Addr) @?= IPv4Addr 0xFFFFFFFF   ]  ipv6Tests :: TestTree ipv6Tests = testGroup "IPv6"   [ testCase "parses sample IPs" $ do-      readIPv6 "::" @?= Just (IPv6 0 0 0 0)-      readIPv6 "::1" @?= Just (IPv6 0 0 0 1)-      readIPv6 "::2" @?= Just (IPv6 0 0 0 2)-      readIPv6 "::ffff" @?= Just (IPv6 0 0 0 0xFFFF)-      readIPv6 "::ff:ffff" @?= Just (IPv6 0 0 0 0xFFFFFF)-      readIPv6 "::ffff:ffff" @?= Just (IPv6 0 0 0 0xFFFFFFFF)-      readIPv6 "2001:0DB8:AC10:FE01:0000:0000:0000:0000" @?=-        Just (IPv6 0x20010DB8 0xAC10FE01 0 0)-      readIPv6 "2001:0DB8:AC10:FE01:0:0:0:0" @?=-        Just (IPv6 0x20010DB8 0xAC10FE01 0 0)-      readIPv6 "2001:db8:ac10:fe01::" @?=-        Just (IPv6 0x20010DB8 0xAC10FE01 0 0)+      readIPv6Addr "::" @?= Just (IPv6Addr 0 0 0 0)+      readIPv6Addr "::1" @?= Just (IPv6Addr 0 0 0 1)+      readIPv6Addr "::2" @?= Just (IPv6Addr 0 0 0 2)+      readIPv6Addr "::ffff" @?= Just (IPv6Addr 0 0 0 0xFFFF)+      readIPv6Addr "::ff:ffff" @?= Just (IPv6Addr 0 0 0 0xFFFFFF)+      readIPv6Addr "::ffff:ffff" @?= Just (IPv6Addr 0 0 0 0xFFFFFFFF)+      readIPv6Addr "2001:0DB8:AC10:FE01:0000:0000:0000:0000" @?=+        Just (IPv6Addr 0x20010DB8 0xAC10FE01 0 0)+      readIPv6Addr "2001:0DB8:AC10:FE01:0:0:0:0" @?=+        Just (IPv6Addr 0x20010DB8 0xAC10FE01 0 0)+      readIPv6Addr "2001:db8:ac10:fe01::" @?=+        Just (IPv6Addr 0x20010DB8 0xAC10FE01 0 0)    , testCase "round trips RFC 5952 IPs" $-    mapM_ (\t -> toText (fromJust (readIPv6 t)) @?= t)+    mapM_ (\t -> toText (fromJust (readIPv6Addr t)) @?= t)     [ "::"     , "::1"     , "::1:1"@@ -78,11 +78,12 @@     ]    , QC.testProperty "round trips arbitrary IPs" $-    \ip -> readIPv6 (toText (ip :: IPv6)) == Just ip+    \ip -> readIPv6Addr (toText (ip :: IPv6Addr)) == Just ip    , testCase "Bounded instance" $ do-      (minBound :: IPv6) @?= IPv6 0 0 0 0-      (maxBound :: IPv6) @?= IPv6 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF+      (minBound :: IPv6Addr) @?= IPv6Addr 0 0 0 0+      (maxBound :: IPv6Addr) @?=+        IPv6Addr 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF   ]  multiaddrTests :: TestTree