hw-ip 0.1.0.0 → 0.2.0.0
raw patch · 5 files changed
+134/−49 lines, 5 filesdep +attoparsecdep +generic-lensdep +hw-bitsPVP ok
version bump matches the API change (PVP)
Dependencies added: attoparsec, generic-lens, hw-bits, text
API changes (from Hackage documentation)
- HaskellWorks.Data.Network.Ip: [ipv4BlockBase] :: Ipv4Block -> Ipv4Address
- HaskellWorks.Data.Network.Ip: [ipv4BlockMask] :: Ipv4Block -> Ipv4NetMask
- HaskellWorks.Data.Network.Ip: [unIpv4Address] :: Ipv4Address -> Word32
- HaskellWorks.Data.Network.Ip: [unIpv4NetMask] :: Ipv4NetMask -> Word8
- HaskellWorks.Data.Network.Ip: instance GHC.Classes.Eq HaskellWorks.Data.Network.Ip.Ipv4Address
- HaskellWorks.Data.Network.Ip: instance GHC.Classes.Eq HaskellWorks.Data.Network.Ip.Ipv4Block
- HaskellWorks.Data.Network.Ip: instance GHC.Classes.Eq HaskellWorks.Data.Network.Ip.Ipv4NetMask
- HaskellWorks.Data.Network.Ip: instance GHC.Classes.Ord HaskellWorks.Data.Network.Ip.Ipv4Address
- HaskellWorks.Data.Network.Ip: instance GHC.Classes.Ord HaskellWorks.Data.Network.Ip.Ipv4Block
- HaskellWorks.Data.Network.Ip: instance GHC.Classes.Ord HaskellWorks.Data.Network.Ip.Ipv4NetMask
- HaskellWorks.Data.Network.Ip: instance GHC.Enum.Enum HaskellWorks.Data.Network.Ip.Ipv4Address
- HaskellWorks.Data.Network.Ip: instance GHC.Enum.Enum HaskellWorks.Data.Network.Ip.Ipv4NetMask
- HaskellWorks.Data.Network.Ip: instance GHC.Show.Show HaskellWorks.Data.Network.Ip.Ipv4Address
- HaskellWorks.Data.Network.Ip: instance GHC.Show.Show HaskellWorks.Data.Network.Ip.Ipv4Block
- HaskellWorks.Data.Network.Ip: instance GHC.Show.Show HaskellWorks.Data.Network.Ip.Ipv4NetMask
- HaskellWorks.Data.Network.Ip: Ipv4Block :: Ipv4Address -> Ipv4NetMask -> Ipv4Block
+ HaskellWorks.Data.Network.Ip: Ipv4Block :: !Ipv4Address -> !Ipv4NetMask -> Ipv4Block
- HaskellWorks.Data.Network.Ip: bitPower :: Ipv4NetMask -> Int
+ HaskellWorks.Data.Network.Ip: bitPower :: Ipv4NetMask -> Word64
Files
- LICENSE +1/−1
- hw-ip.cabal +15/−8
- src/HaskellWorks/Data/Network/Ip.hs +20/−40
- src/HaskellWorks/Data/Network/Ip/Internal.hs +47/−0
- src/HaskellWorks/Data/Network/Ip/Type.hs +51/−0
LICENSE view
@@ -1,4 +1,4 @@-Copyright Author name here (c) 2017+Copyright John Ky (c) 2017-2018 All rights reserved.
hw-ip.cabal view
@@ -1,11 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.20.0.+-- This file has been generated from package.yaml by hpack version 0.18.1. -- -- see: https://github.com/sol/hpack------ hash: 0e009dc6f8e47e478d23c2015665d88494848c9a86e5c1b03550fe2351cda87e name: hw-ip-version: 0.1.0.0+version: 0.2.0.0 synopsis: Library for manipulating IP addresses and CIDR blocks description: Please see README.md category: Network@@ -30,10 +28,16 @@ hs-source-dirs: src build-depends:- base >=4.7 && <5+ attoparsec+ , generic-lens+ , hw-bits+ , text+ , base >=4.7 && <5 exposed-modules: HaskellWorks.Data.Network.Ip other-modules:+ HaskellWorks.Data.Network.Ip.Internal+ HaskellWorks.Data.Network.Ip.Type Paths_hw_ip default-language: Haskell2010 @@ -44,12 +48,15 @@ test ghc-options: -threaded -rtsopts -with-rtsopts=-N build-depends:- base+ attoparsec+ , generic-lens+ , hw-bits+ , text+ , base , hedgehog- , hspec , hw-hspec-hedgehog , hw-ip+ , hspec other-modules: HaskellWorks.Data.Network.IpSpec- Paths_hw_ip default-language: Haskell2010
src/HaskellWorks/Data/Network/Ip.hs view
@@ -1,59 +1,39 @@-{-# LANGUAGE BangPatterns #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DuplicateRecordFields #-} module HaskellWorks.Data.Network.Ip- ( Ipv4Address(..)- , Ipv4NetMask(..)- , Ipv4Block(..)+ ( Z.Ipv4Address(Ipv4Address)+ , Z.Ipv4NetMask(Ipv4NetMask)+ , Z.Ipv4Block(Ipv4Block) , bitPower , blockSize , isCanonical , splitBlock ) where -import Data.Bits import Data.Word--newtype Ipv4Address = Ipv4Address- { unIpv4Address :: Word32- } deriving (Enum, Eq, Ord)--instance Show Ipv4Address where- showsPrec _ (Ipv4Address w) =- shows ((w `shiftR` 24) .&. 0xff) . ('.':) .- shows ((w `shiftR` 16) .&. 0xff) . ('.':) .- shows ((w `shiftR` 8) .&. 0xff) . ('.':) .- shows ( w .&. 0xff)--newtype Ipv4NetMask = Ipv4NetMask- { unIpv4NetMask :: Word8- } deriving (Enum, Eq, Ord, Show)--data Ipv4Block = Ipv4Block- { ipv4BlockBase :: Ipv4Address- , ipv4BlockMask :: Ipv4NetMask- } deriving (Eq, Ord)+import GHC.Generics+import HaskellWorks.Data.Bits.BitWise -instance Show Ipv4Block where- showsPrec _ (Ipv4Block b (Ipv4NetMask m)) = shows b . ('/':) . shows m+import qualified HaskellWorks.Data.Network.Ip.Type as Z -bitPower :: Ipv4NetMask -> Int-bitPower (Ipv4NetMask m) = fromIntegral (32 - m)+bitPower :: Z.Ipv4NetMask -> Word64+bitPower (Z.Ipv4NetMask m) = fromIntegral (32 - m) -isCanonical :: Ipv4Block -> Bool-isCanonical (Ipv4Block (Ipv4Address b) m) = ((b `shiftR` bitPower m) `shiftL` bitPower m) == b+isCanonical :: Z.Ipv4Block -> Bool+isCanonical (Z.Ipv4Block (Z.Ipv4Address b) m) = ((b .>. bitPower m) .<. bitPower m) == b -splitBlock :: Ipv4Block -> Maybe (Ipv4Block, Ipv4Block)-splitBlock (Ipv4Block (Ipv4Address b) (Ipv4NetMask m)) =+splitBlock :: Z.Ipv4Block -> Maybe (Z.Ipv4Block, Z.Ipv4Block)+splitBlock (Z.Ipv4Block (Z.Ipv4Address b) (Z.Ipv4NetMask m)) = if m >= 0 && m < 32 then let !hm = m + 1- !halfMask = Ipv4NetMask hm- !c = fromIntegral ((0x100000000 :: Word64) `shiftR` fromIntegral (m + 1))+ !halfMask = Z.Ipv4NetMask hm+ !c = fromIntegral ((0x100000000 :: Word64) .>. fromIntegral (m + 1)) in Just- ( Ipv4Block (Ipv4Address b ) halfMask- , Ipv4Block (Ipv4Address (b + c)) halfMask+ ( Z.Ipv4Block (Z.Ipv4Address b ) halfMask+ , Z.Ipv4Block (Z.Ipv4Address (b + c)) halfMask ) else Nothing -blockSize :: Ipv4Block -> Int-blockSize (Ipv4Block _ m) = 2 ^ bitPower m+blockSize :: Z.Ipv4Block -> Int+blockSize (Z.Ipv4Block _ m) = 2 ^ bitPower m
+ src/HaskellWorks/Data/Network/Ip/Internal.hs view
@@ -0,0 +1,47 @@+{-# LANGUAGE OverloadedStrings #-}++module HaskellWorks.Data.Network.Ip.Internal where++import Control.Applicative+import Control.Monad+import Data.Char+import Data.Word+import HaskellWorks.Data.Bits.BitWise++import qualified Data.Attoparsec.Text as AP++fourOctetsToWord32 :: Word8 -> Word8 -> Word8 -> Word8 -> Word32+fourOctetsToWord32 a b c d =+ (fromIntegral a .<. 24) .|.+ (fromIntegral b .<. 16) .|.+ (fromIntegral c .<. 8) .|.+ fromIntegral d+{-# INLINE fourOctetsToWord32 #-}++infixl 2 #<*>#++(#<*>#) :: 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)+ <|> ( d19 #<*># d09)+ <|> d09+ where d5 = fromIntegral . (+ (-48)) . ord <$> AP.satisfy (== '5')+ 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')++ipv4Address :: AP.Parser Word32+ipv4Address = fourOctetsToWord32+ <$> (octet <* AP.char '.')+ <*> (octet <* AP.char '.')+ <*> (octet <* AP.char '.')+ <*> octet++whitespace :: AP.Parser ()+whitespace = void $ many (AP.satisfy isSpace)
+ src/HaskellWorks/Data/Network/Ip/Type.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE DuplicateRecordFields #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE InstanceSigs #-}++module HaskellWorks.Data.Network.Ip.Type+ ( Ipv4Address(..)+ , Ipv4NetMask(..)+ , Ipv4Block(..)+ ) where++import Data.Word+import GHC.Generics+import HaskellWorks.Data.Bits.BitWise++import qualified Data.Attoparsec.Text as AP+import qualified Data.Text as T+import qualified HaskellWorks.Data.Network.Ip.Internal as I+import qualified Text.ParserCombinators.ReadPrec as RP++newtype Ipv4Address = Ipv4Address+ { word :: Word32+ } deriving (Enum, Eq, Ord, Generic)++instance Show Ipv4Address where+ showsPrec _ (Ipv4Address w) =+ shows ((w .>. 24) .&. 0xff) . ('.':) .+ shows ((w .>. 16) .&. 0xff) . ('.':) .+ shows ((w .>. 8) .&. 0xff) . ('.':) .+ shows ( w .&. 0xff)++instance Read Ipv4Address where+ readsPrec :: Int -> String -> [(Ipv4Address, String)]+ readsPrec _ s = case AP.parseWith (return mempty) (I.whitespace *> I.ipv4Address) (T.pack s) of+ Just result -> case result of+ AP.Done i r -> [(Ipv4Address r, T.unpack i)]+ AP.Partial _ -> []+ AP.Fail a b c -> []+ Nothing -> []++newtype Ipv4NetMask = Ipv4NetMask+ { word :: Word8+ } deriving (Enum, Eq, Ord, Show, Generic)++data Ipv4Block = Ipv4Block+ { base :: !Ipv4Address+ , mask :: !Ipv4NetMask+ } deriving (Eq, Ord)++instance Show Ipv4Block where+ showsPrec _ (Ipv4Block b (Ipv4NetMask m)) = shows b . ('/':) . shows m