hs-multiaddr-0.1.0.0: src/Data/Multiaddr/Port.hs
{-# LANGUAGE DeriveGeneric #-}
module Data.Multiaddr.Port
(
Port (..),
toString,
parse,
encode,
parseB,
toPort,
fromPort
) where
import qualified Text.ParserCombinators.ReadP as Parser
import qualified Data.ByteString as BSStrict
import qualified Data.Multiaddr.VarInt as VarInt
import GHC.Generics (Generic)
import Data.Word (Word16)
import Data.Char (isDigit)
import Data.Bytes.Get (runGetS)
import Data.Bytes.Put (runPutS)
import Data.Bytes.Serial (serialize, deserialize)
import Data.Serialize.Get (Get)
newtype Port = Port
{
port :: Word16
}
deriving (Show, Eq, Ord, Generic)
toPort :: (Integral a, Eq a) => a -> Maybe Port
toPort n | n < 0 || n > 65535 = Nothing
| otherwise = Just $ Port (fromIntegral n)
fromPort :: Integral a => Port -> a
fromPort p = fromIntegral (port p)
toString :: Port -> String
toString (Port p) = show p
parse :: Parser.ReadP Port
parse = do
port <- fmap read $ rangeParse (Parser.satisfy isDigit) 1 5 :: Parser.ReadP Int
case toPort port of
Just p -> return p
Nothing -> Parser.pfail
rangeParse :: Read a => Parser.ReadP a -> Int -> Int -> Parser.ReadP [a]
rangeParse parse min max = foldr1 (Parser.<++) $
fmap (\n -> Parser.count n $ parse) [max, max-1..min]
encode :: Port -> BSStrict.ByteString
encode (Port p) = (runPutS . serialize) $ p
parseB :: Get Port
parseB =
VarInt.decodeSize 16 >>=
(either fail (return . Port) . runGetS deserialize)