packages feed

IPv6Addr 2.0.6.2 → 3.0.0.0

raw patch · 4 files changed

+88/−61 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Text.IPv6Addr: sameIPv6Addr :: Text -> Text -> Bool

Files

+ CHANGELOG.md view
@@ -0,0 +1,6 @@+# Revision history for IPv6Addr++## 3.0.0.0 -- 2026-06-11++* Performance optimizations+* Deprecated sameIPv6Addr removed
IPv6Addr.cabal view
@@ -1,19 +1,21 @@-name:                IPv6Addr-version:             2.0.6.2-synopsis:            Library to deal with IPv6 address text representations.-description:         Library to deal with IPv6 address text representations, canonization and manipulations.-homepage:            https://github.com/MichelBoucey/IPv6Addr-license:             BSD3-license-file:        LICENSE-author:              Michel Boucey-maintainer:          michel.boucey@gmail.com-copyright:           (c) 2011-2025 - Michel Boucey-category:            Network-build-type:          Simple-extra-source-files:  README.md-cabal-version:       >=1.10+cabal-version:      3.0+name:               IPv6Addr+version:            3.0.0.0+synopsis:           Library to deal with IPv6 address text representations.+description:+  Library to deal with IPv6 address text representations, canonization and manipulations. -Tested-With:+homepage:           https://github.com/MichelBoucey/IPv6Addr+license:            BSD-3-Clause+license-file:       LICENSE+author:             Michel Boucey+maintainer:         michel.boucey@gmail.com+copyright:          (c) 2011-2026 - Michel Boucey+category:           Network+build-type:         Simple+extra-source-files: README.md+extra-doc-files:    CHANGELOG.md+tested-with:   GHC ==8.8.4    || ==8.10.7    || ==9.0.2@@ -25,33 +27,35 @@    || ==9.12.2    || ==9.14.1 -Source-Repository head-  Type: git-  Location: https://github.com/MichelBoucey/IPv6Addr.git+source-repository head+  type:     git+  location: https://github.com/MichelBoucey/IPv6Addr.git  library   hs-source-dirs:   src/   exposed-modules:  Text.IPv6Addr   other-extensions: OverloadedStrings-  build-depends:    base         >=4.8 && < 5-                  , text         >=1.1 && < 2.2-                  , iproute      >=1.3 && < 1.8-                  , network      >=2.5 && < 4-                  , random       >=1.0 && < 1.4-                  , attoparsec   >=0.12 && < 0.15-                  , aeson        >=2.2.3 && < 2.4-                  , network-info >=0.2 && <0.3-  default-language: Haskell2010-  GHC-Options:      -Wall+  build-depends:+      aeson         >=2.2.3 && <2.4+    , attoparsec    >=0.12  && <0.15+    , base          >=4.8   && <5+    , iproute       >=1.3   && <1.8+    , network       >=2.5   && <4+    , network-info  >=0.2   && <0.3+    , random        >=1.0   && <1.4+    , text          >=1.1   && <2.2 -Test-Suite tests-  Type:             exitcode-stdio-1.0   default-language: Haskell2010-  HS-Source-Dirs:   tests-  Main-Is:          Main.hs-  Build-Depends:    base-                  , HUnit-                  , IPv6Addr-                  , test-framework-                  , test-framework-hunit+  ghc-options:      -Wall +test-suite tests+  type:             exitcode-stdio-1.0+  default-language: Haskell2010+  hs-source-dirs:   tests+  main-is:          Main.hs+  build-depends:+      base+    , HUnit+    , IPv6Addr+    , test-framework+    , test-framework-hunit
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2011-2025, Michel Boucey+Copyright (c) 2011-2026, Michel Boucey All rights reserved.  Redistribution and use in source and binary forms, with or without
src/Text/IPv6Addr.hs view
@@ -6,7 +6,6 @@     , maybeIPv6Addr     , maybePureIPv6Addr     , maybeFullIPv6Addr-    , sameIPv6Addr      -- * Conversions     , toIPv6@@ -32,7 +31,7 @@ import           Data.Aeson import           Data.Attoparsec.Text import           Data.Char            (intToDigit, isDigit)-import           Data.IP              (IPv6)+import qualified Data.IP              as IP (IPv6, fromIPv6b, toIPv6)  #if !MIN_VERSION_base(4,20,0) import           Data.List            (elemIndex, elemIndices, foldl', group,@@ -49,7 +48,7 @@ import           Data.Monoid          ((<>)) #endif -import qualified Data.Text            as T hiding (foldl')+import qualified Data.Text            as T import qualified Data.Text.Read       as R (decimal)  #if MIN_VERSION_network (2,7,0)@@ -68,8 +67,7 @@   show (IPv6Addr a) = T.unpack a  instance Eq IPv6Addr where-  (==) (IPv6Addr a) (IPv6Addr b) =-    (unIPv6Addr <$> maybePureIPv6Addr a) == (unIPv6Addr <$> maybePureIPv6Addr b)+  (==) a b = toIPv6 a == toIPv6 b  instance ToJSON IPv6Addr where   toJSON (IPv6Addr a) = String a@@ -113,27 +111,17 @@   maybeTokPureIPv6Addr t >>=     (ipv6TokensToIPv6Addr . expandTokens . fromDoubleColon) --- | Returns 'True' if arguments are two textual representations of a same IPv6 address.-{-# DEPRECATED sameIPv6Addr "Use the Eq instance." #-}-sameIPv6Addr :: T.Text -> T.Text -> Bool-sameIPv6Addr a b =-  case maybePureIPv6Addr a of-    Nothing -> False-    Just a' ->-      case maybePureIPv6Addr b of-        Nothing -> False-        Just b' -> a' == b'- -- | Returns the reverse lookup domain name corresponding of the given IPv6 address (RFC 3596 Section 2.5). -- -- > toIP6ARPA (IPv6Addr "4321:0:1:2:3:4:567:89ab") == "b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.IP6.ARPA." -- toIP6ARPA :: IPv6Addr -> T.Text toIP6ARPA a =-  T.reverse (T.concatMap go $ unIPv6Addr $ fromJust $ maybeFullIPv6Addr $ unIPv6Addr a) <> "IP6.ARPA."+  T.intercalate "."+    (T.singleton <$> reverse (concatMap padHex2 (IP.fromIPv6b (toIPv6 a))))+  <> ".IP6.ARPA."   where-    go ':' = T.empty-    go c   = "." <> T.pack [c]+    padHex2 n = let s = showHex n "" in replicate (2 - length s) '0' <> s  -- | Returns the Windows UNC path name of the given IPv6 Address. --@@ -141,18 +129,21 @@ -- toUNC :: IPv6Addr -> T.Text toUNC a =-  T.concatMap go (unIPv6Addr $ fromJust $ maybePureIPv6Addr $ unIPv6Addr a) <> ".ipv6-literal.net"+  T.concatMap go (T.pack $ show $ toIPv6 a) <> ".ipv6-literal.net"   where     go ':' = "-"-    go c   = T.pack [c]+    go c   = T.singleton c  -- | Given an 'IPv6Addr', returns the corresponding 'HostName'. toHostName :: IPv6Addr -> HostName toHostName = show  -- | Given an 'IPv6Addr', returns the corresponding 'Data.IP.IPv6' address.-toIPv6 :: IPv6Addr -> Data.IP.IPv6-toIPv6 = read . show+toIPv6 :: IPv6Addr -> IP.IPv6+toIPv6 a =+  case maybeTokPureIPv6Addr (unIPv6Addr a) >>= tokensToIPv6 of+    Just v  -> v+    Nothing -> read (T.unpack $ unIPv6Addr a)  -- | Returns 'Just' the canonized 'IPv6Addr' of the given local network interface, -- or 'Nothing'.@@ -511,6 +502,32 @@  ipv6TokensToIPv6Addr :: [IPv6AddrToken] -> Maybe IPv6Addr ipv6TokensToIPv6Addr = Just . IPv6Addr . ipv6TokensToText++hexTextToInt :: T.Text -> Int+hexTextToInt =+  T.foldl' (\n c -> n * 16 + hexDigitToInt c) 0+  where+    hexDigitToInt :: Char -> Int+    hexDigitToInt c+      | '0' <= c && c <= '9' = fromEnum c - fromEnum '0'+      | 'a' <= c && c <= 'f' = fromEnum c - fromEnum 'a' + 10+      | 'A' <= c && c <= 'F' = fromEnum c - fromEnum 'A' + 10+      | otherwise            = 0++-- | Convert pure IPv6 tokens (after fromDoubleColon) to 'Data.IP.IPv6' directly.+tokensToIPv6 :: [IPv6AddrToken] -> Maybe IP.IPv6+tokensToIPv6 tks = do+  let expanded = fromDoubleColon tks+      chunks   = filter isChunk expanded+  guard (length chunks == 8)+  Just $ IP.toIPv6 (map chunkToInt chunks)+  where+    isChunk SixteenBit{} = True+    isChunk AllZeros     = True+    isChunk _            = False+    chunkToInt AllZeros       = 0+    chunkToInt (SixteenBit s) = hexTextToInt s+    chunkToInt _              = 0  networkInterfacesIPv6AddrList :: IO [(String,Network.Info.IPv6)] networkInterfacesIPv6AddrList =