{-# LANGUAGE DeriveFunctor              #-}
{-# LANGUAGE DerivingStrategies         #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
{-# LANGUAGE ImportQualifiedPost        #-}
{-# LANGUAGE MonoLocalBinds             #-}
{-# LANGUAGE NamedFieldPuns             #-}
{-# LANGUAGE OverloadedStrings          #-}

module Cardano.Node.Configuration.NodeAddress
  ( -- * Node addresses
    NodeAddress'(..)
  , NodeIPAddress
  , nodeAddressToSockAddr
  , NodeIPv4Address
  , NodeIPv6Address
  , NodeDnsAddress
  , nodeIPv4ToIPAddress
  , nodeIPv6ToIPAddress
  , nodeDnsAddressToDomainAddress
  , NodeHostIPAddress (..)
  , nodeHostIPAddressToSockAddr
  , NodeHostIPv4Address (..)
  , NodeHostIPv6Address (..)
  , nodeHostIPv4AddressToIPAddress
  , nodeHostIPv6AddressToIPAddress
  , NodeHostDnsAddress (..)
  , nodeHostDnsAddressToDomain
  , PortNumber
  , SocketPath(..)
  ) where

import Cardano.Prelude
import Prelude (fail)

import Data.Aeson (FromJSON (..), ToJSON (..), Value (..),
                   (.:), (.=), withObject, object)
import Data.IP (IP (..), IPv4, IPv6)
import Data.IP qualified as IP
import Data.Text qualified as Text
import Data.Text.Encoding qualified as Text
import Network.DNS qualified as DNS (Domain)
import Network.Socket (PortNumber, SockAddr (..))

import Ouroboros.Network.PeerSelection.RootPeersDNS (DomainAccessPoint (..))


-- | IPv4 or IPv6 address with a port number.
data NodeAddress' addr = NodeAddress
  { NodeAddress' addr -> addr
naHostAddress :: !addr
  , NodeAddress' addr -> PortNumber
naPort        :: !PortNumber
  } deriving (NodeAddress' addr -> NodeAddress' addr -> Bool
(NodeAddress' addr -> NodeAddress' addr -> Bool)
-> (NodeAddress' addr -> NodeAddress' addr -> Bool)
-> Eq (NodeAddress' addr)
forall addr.
Eq addr =>
NodeAddress' addr -> NodeAddress' addr -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NodeAddress' addr -> NodeAddress' addr -> Bool
$c/= :: forall addr.
Eq addr =>
NodeAddress' addr -> NodeAddress' addr -> Bool
== :: NodeAddress' addr -> NodeAddress' addr -> Bool
$c== :: forall addr.
Eq addr =>
NodeAddress' addr -> NodeAddress' addr -> Bool
Eq, Eq (NodeAddress' addr)
Eq (NodeAddress' addr)
-> (NodeAddress' addr -> NodeAddress' addr -> Ordering)
-> (NodeAddress' addr -> NodeAddress' addr -> Bool)
-> (NodeAddress' addr -> NodeAddress' addr -> Bool)
-> (NodeAddress' addr -> NodeAddress' addr -> Bool)
-> (NodeAddress' addr -> NodeAddress' addr -> Bool)
-> (NodeAddress' addr -> NodeAddress' addr -> NodeAddress' addr)
-> (NodeAddress' addr -> NodeAddress' addr -> NodeAddress' addr)
-> Ord (NodeAddress' addr)
NodeAddress' addr -> NodeAddress' addr -> Bool
NodeAddress' addr -> NodeAddress' addr -> Ordering
NodeAddress' addr -> NodeAddress' addr -> NodeAddress' addr
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall addr. Ord addr => Eq (NodeAddress' addr)
forall addr.
Ord addr =>
NodeAddress' addr -> NodeAddress' addr -> Bool
forall addr.
Ord addr =>
NodeAddress' addr -> NodeAddress' addr -> Ordering
forall addr.
Ord addr =>
NodeAddress' addr -> NodeAddress' addr -> NodeAddress' addr
min :: NodeAddress' addr -> NodeAddress' addr -> NodeAddress' addr
$cmin :: forall addr.
Ord addr =>
NodeAddress' addr -> NodeAddress' addr -> NodeAddress' addr
max :: NodeAddress' addr -> NodeAddress' addr -> NodeAddress' addr
$cmax :: forall addr.
Ord addr =>
NodeAddress' addr -> NodeAddress' addr -> NodeAddress' addr
>= :: NodeAddress' addr -> NodeAddress' addr -> Bool
$c>= :: forall addr.
Ord addr =>
NodeAddress' addr -> NodeAddress' addr -> Bool
> :: NodeAddress' addr -> NodeAddress' addr -> Bool
$c> :: forall addr.
Ord addr =>
NodeAddress' addr -> NodeAddress' addr -> Bool
<= :: NodeAddress' addr -> NodeAddress' addr -> Bool
$c<= :: forall addr.
Ord addr =>
NodeAddress' addr -> NodeAddress' addr -> Bool
< :: NodeAddress' addr -> NodeAddress' addr -> Bool
$c< :: forall addr.
Ord addr =>
NodeAddress' addr -> NodeAddress' addr -> Bool
compare :: NodeAddress' addr -> NodeAddress' addr -> Ordering
$ccompare :: forall addr.
Ord addr =>
NodeAddress' addr -> NodeAddress' addr -> Ordering
$cp1Ord :: forall addr. Ord addr => Eq (NodeAddress' addr)
Ord, Int -> NodeAddress' addr -> ShowS
[NodeAddress' addr] -> ShowS
NodeAddress' addr -> String
(Int -> NodeAddress' addr -> ShowS)
-> (NodeAddress' addr -> String)
-> ([NodeAddress' addr] -> ShowS)
-> Show (NodeAddress' addr)
forall addr. Show addr => Int -> NodeAddress' addr -> ShowS
forall addr. Show addr => [NodeAddress' addr] -> ShowS
forall addr. Show addr => NodeAddress' addr -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NodeAddress' addr] -> ShowS
$cshowList :: forall addr. Show addr => [NodeAddress' addr] -> ShowS
show :: NodeAddress' addr -> String
$cshow :: forall addr. Show addr => NodeAddress' addr -> String
showsPrec :: Int -> NodeAddress' addr -> ShowS
$cshowsPrec :: forall addr. Show addr => Int -> NodeAddress' addr -> ShowS
Show, a -> NodeAddress' b -> NodeAddress' a
(a -> b) -> NodeAddress' a -> NodeAddress' b
(forall a b. (a -> b) -> NodeAddress' a -> NodeAddress' b)
-> (forall a b. a -> NodeAddress' b -> NodeAddress' a)
-> Functor NodeAddress'
forall a b. a -> NodeAddress' b -> NodeAddress' a
forall a b. (a -> b) -> NodeAddress' a -> NodeAddress' b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> NodeAddress' b -> NodeAddress' a
$c<$ :: forall a b. a -> NodeAddress' b -> NodeAddress' a
fmap :: (a -> b) -> NodeAddress' a -> NodeAddress' b
$cfmap :: forall a b. (a -> b) -> NodeAddress' a -> NodeAddress' b
Functor)

type NodeIPAddress   = NodeAddress' NodeHostIPAddress
type NodeIPv4Address = NodeAddress' NodeHostIPv4Address
type NodeIPv6Address = NodeAddress' NodeHostIPv6Address
type NodeDnsAddress  = NodeAddress' NodeHostDnsAddress

instance FromJSON addr => FromJSON (NodeAddress' addr) where
  parseJSON :: Value -> Parser (NodeAddress' addr)
parseJSON = String
-> (Object -> Parser (NodeAddress' addr))
-> Value
-> Parser (NodeAddress' addr)
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"NodeAddress" ((Object -> Parser (NodeAddress' addr))
 -> Value -> Parser (NodeAddress' addr))
-> (Object -> Parser (NodeAddress' addr))
-> Value
-> Parser (NodeAddress' addr)
forall a b. (a -> b) -> a -> b
$ \Object
v -> do
    addr -> PortNumber -> NodeAddress' addr
forall addr. addr -> PortNumber -> NodeAddress' addr
NodeAddress
      (addr -> PortNumber -> NodeAddress' addr)
-> Parser addr -> Parser (PortNumber -> NodeAddress' addr)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser addr
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"addr"
      Parser (PortNumber -> NodeAddress' addr)
-> Parser PortNumber -> Parser (NodeAddress' addr)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((Int -> PortNumber
forall a b. (Integral a, Num b) => a -> b
fromIntegral :: Int -> PortNumber) (Int -> PortNumber) -> Parser Int -> Parser PortNumber
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser Int
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"port")

instance ToJSON addr => ToJSON (NodeAddress' addr) where
  toJSON :: NodeAddress' addr -> Value
toJSON NodeAddress' addr
na =
    [Pair] -> Value
object
      [ Key
"addr" Key -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= addr -> Value
forall a. ToJSON a => a -> Value
toJSON (NodeAddress' addr -> addr
forall addr. NodeAddress' addr -> addr
naHostAddress NodeAddress' addr
na)
      , Key
"port" Key -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Key -> v -> kv
.= (PortNumber -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (NodeAddress' addr -> PortNumber
forall addr. NodeAddress' addr -> PortNumber
naPort NodeAddress' addr
na) :: Int)
      ]


nodeIPv4ToIPAddress :: NodeIPv4Address -> NodeIPAddress
nodeIPv4ToIPAddress :: NodeIPv4Address -> NodeIPAddress
nodeIPv4ToIPAddress = (NodeHostIPv4Address -> NodeHostIPAddress)
-> NodeIPv4Address -> NodeIPAddress
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NodeHostIPv4Address -> NodeHostIPAddress
nodeHostIPv4AddressToIPAddress

nodeIPv6ToIPAddress :: NodeIPv6Address -> NodeIPAddress
nodeIPv6ToIPAddress :: NodeIPv6Address -> NodeIPAddress
nodeIPv6ToIPAddress = (NodeHostIPv6Address -> NodeHostIPAddress)
-> NodeIPv6Address -> NodeIPAddress
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NodeHostIPv6Address -> NodeHostIPAddress
nodeHostIPv6AddressToIPAddress

nodeDnsAddressToDomainAddress :: NodeDnsAddress -> DomainAccessPoint
nodeDnsAddressToDomainAddress :: NodeDnsAddress -> DomainAccessPoint
nodeDnsAddressToDomainAddress NodeAddress { naHostAddress :: forall addr. NodeAddress' addr -> addr
naHostAddress = NodeHostDnsAddress Text
dns, PortNumber
naPort :: PortNumber
naPort :: forall addr. NodeAddress' addr -> PortNumber
naPort }
  = Domain -> PortNumber -> DomainAccessPoint
DomainAccessPoint (Text -> Domain
Text.encodeUtf8 Text
dns) PortNumber
naPort

nodeAddressToSockAddr :: NodeIPAddress -> SockAddr
nodeAddressToSockAddr :: NodeIPAddress -> SockAddr
nodeAddressToSockAddr (NodeAddress NodeHostIPAddress
addr PortNumber
port) =
  case NodeHostIPAddress -> IP
unNodeHostIPAddress NodeHostIPAddress
addr of
    IP.IPv4 IPv4
ipv4 -> PortNumber -> HostAddress -> SockAddr
SockAddrInet  PortNumber
port   (IPv4 -> HostAddress
IP.toHostAddress IPv4
ipv4)
    IP.IPv6 IPv6
ipv6 -> PortNumber
-> HostAddress -> HostAddress6 -> HostAddress -> SockAddr
SockAddrInet6 PortNumber
port HostAddress
0 (IPv6 -> HostAddress6
IP.toHostAddress6 IPv6
ipv6) HostAddress
0

nodeHostIPAddressToSockAddr :: NodeIPAddress -> SockAddr
nodeHostIPAddressToSockAddr :: NodeIPAddress -> SockAddr
nodeHostIPAddressToSockAddr NodeAddress { naHostAddress :: forall addr. NodeAddress' addr -> addr
naHostAddress = NodeHostIPAddress IP
ip, PortNumber
naPort :: PortNumber
naPort :: forall addr. NodeAddress' addr -> PortNumber
naPort } =
  case IP
ip of
    IPv4 IPv4
ipv4 -> PortNumber -> HostAddress -> SockAddr
SockAddrInet  (PortNumber -> PortNumber
forall a b. (Integral a, Num b) => a -> b
fromIntegral PortNumber
naPort)   (IPv4 -> HostAddress
IP.toHostAddress IPv4
ipv4)
    IPv6 IPv6
ipv6 -> PortNumber
-> HostAddress -> HostAddress6 -> HostAddress -> SockAddr
SockAddrInet6 (PortNumber -> PortNumber
forall a b. (Integral a, Num b) => a -> b
fromIntegral PortNumber
naPort) HostAddress
0 (IPv6 -> HostAddress6
IP.toHostAddress6 IPv6
ipv6) HostAddress
0


newtype NodeHostIPv4Address
  = NodeHostIPv4Address { NodeHostIPv4Address -> IPv4
unNodeHostIPv4Address :: IPv4 }
  deriving newtype Int -> NodeHostIPv4Address -> ShowS
[NodeHostIPv4Address] -> ShowS
NodeHostIPv4Address -> String
(Int -> NodeHostIPv4Address -> ShowS)
-> (NodeHostIPv4Address -> String)
-> ([NodeHostIPv4Address] -> ShowS)
-> Show NodeHostIPv4Address
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NodeHostIPv4Address] -> ShowS
$cshowList :: [NodeHostIPv4Address] -> ShowS
show :: NodeHostIPv4Address -> String
$cshow :: NodeHostIPv4Address -> String
showsPrec :: Int -> NodeHostIPv4Address -> ShowS
$cshowsPrec :: Int -> NodeHostIPv4Address -> ShowS
Show
  deriving (NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
(NodeHostIPv4Address -> NodeHostIPv4Address -> Bool)
-> (NodeHostIPv4Address -> NodeHostIPv4Address -> Bool)
-> Eq NodeHostIPv4Address
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
$c/= :: NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
== :: NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
$c== :: NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
Eq, Eq NodeHostIPv4Address
Eq NodeHostIPv4Address
-> (NodeHostIPv4Address -> NodeHostIPv4Address -> Ordering)
-> (NodeHostIPv4Address -> NodeHostIPv4Address -> Bool)
-> (NodeHostIPv4Address -> NodeHostIPv4Address -> Bool)
-> (NodeHostIPv4Address -> NodeHostIPv4Address -> Bool)
-> (NodeHostIPv4Address -> NodeHostIPv4Address -> Bool)
-> (NodeHostIPv4Address
    -> NodeHostIPv4Address -> NodeHostIPv4Address)
-> (NodeHostIPv4Address
    -> NodeHostIPv4Address -> NodeHostIPv4Address)
-> Ord NodeHostIPv4Address
NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
NodeHostIPv4Address -> NodeHostIPv4Address -> Ordering
NodeHostIPv4Address -> NodeHostIPv4Address -> NodeHostIPv4Address
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NodeHostIPv4Address -> NodeHostIPv4Address -> NodeHostIPv4Address
$cmin :: NodeHostIPv4Address -> NodeHostIPv4Address -> NodeHostIPv4Address
max :: NodeHostIPv4Address -> NodeHostIPv4Address -> NodeHostIPv4Address
$cmax :: NodeHostIPv4Address -> NodeHostIPv4Address -> NodeHostIPv4Address
>= :: NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
$c>= :: NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
> :: NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
$c> :: NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
<= :: NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
$c<= :: NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
< :: NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
$c< :: NodeHostIPv4Address -> NodeHostIPv4Address -> Bool
compare :: NodeHostIPv4Address -> NodeHostIPv4Address -> Ordering
$ccompare :: NodeHostIPv4Address -> NodeHostIPv4Address -> Ordering
$cp1Ord :: Eq NodeHostIPv4Address
Ord)

instance FromJSON NodeHostIPv4Address where
  parseJSON :: Value -> Parser NodeHostIPv4Address
parseJSON (String Text
ipStr) =
    case String -> Maybe IPv4
forall a. Read a => String -> Maybe a
readMaybe (String -> Maybe IPv4) -> String -> Maybe IPv4
forall a b. (a -> b) -> a -> b
$ Text -> String
Text.unpack Text
ipStr of
      Just IPv4
ip -> NodeHostIPv4Address -> Parser NodeHostIPv4Address
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NodeHostIPv4Address -> Parser NodeHostIPv4Address)
-> NodeHostIPv4Address -> Parser NodeHostIPv4Address
forall a b. (a -> b) -> a -> b
$ IPv4 -> NodeHostIPv4Address
NodeHostIPv4Address IPv4
ip
      Maybe IPv4
Nothing -> String -> Parser NodeHostIPv4Address
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser NodeHostIPv4Address)
-> String -> Parser NodeHostIPv4Address
forall a b. (a -> b) -> a -> b
$ String
"Parsing of IPv4 failed: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
Text.unpack Text
ipStr
  parseJSON Value
invalid = String -> Parser NodeHostIPv4Address
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser NodeHostIPv4Address)
-> String -> Parser NodeHostIPv4Address
forall a b. (a -> b) -> a -> b
$ String
"Parsing of IPv4 failed due to type mismatch. "
                           String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"Encountered: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Value -> String
forall a b. (Show a, ConvertText String b) => a -> b
show Value
invalid String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"\n"

instance ToJSON NodeHostIPv4Address where
  toJSON :: NodeHostIPv4Address -> Value
toJSON (NodeHostIPv4Address IPv4
ip) = Text -> Value
String (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ IPv4 -> String
forall a b. (Show a, ConvertText String b) => a -> b
show IPv4
ip)


newtype NodeHostIPv6Address
  = NodeHostIPv6Address { NodeHostIPv6Address -> IPv6
unNodeHostIPv6Address :: IPv6 }
  deriving newtype Int -> NodeHostIPv6Address -> ShowS
[NodeHostIPv6Address] -> ShowS
NodeHostIPv6Address -> String
(Int -> NodeHostIPv6Address -> ShowS)
-> (NodeHostIPv6Address -> String)
-> ([NodeHostIPv6Address] -> ShowS)
-> Show NodeHostIPv6Address
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NodeHostIPv6Address] -> ShowS
$cshowList :: [NodeHostIPv6Address] -> ShowS
show :: NodeHostIPv6Address -> String
$cshow :: NodeHostIPv6Address -> String
showsPrec :: Int -> NodeHostIPv6Address -> ShowS
$cshowsPrec :: Int -> NodeHostIPv6Address -> ShowS
Show
  deriving (NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
(NodeHostIPv6Address -> NodeHostIPv6Address -> Bool)
-> (NodeHostIPv6Address -> NodeHostIPv6Address -> Bool)
-> Eq NodeHostIPv6Address
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
$c/= :: NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
== :: NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
$c== :: NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
Eq, Eq NodeHostIPv6Address
Eq NodeHostIPv6Address
-> (NodeHostIPv6Address -> NodeHostIPv6Address -> Ordering)
-> (NodeHostIPv6Address -> NodeHostIPv6Address -> Bool)
-> (NodeHostIPv6Address -> NodeHostIPv6Address -> Bool)
-> (NodeHostIPv6Address -> NodeHostIPv6Address -> Bool)
-> (NodeHostIPv6Address -> NodeHostIPv6Address -> Bool)
-> (NodeHostIPv6Address
    -> NodeHostIPv6Address -> NodeHostIPv6Address)
-> (NodeHostIPv6Address
    -> NodeHostIPv6Address -> NodeHostIPv6Address)
-> Ord NodeHostIPv6Address
NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
NodeHostIPv6Address -> NodeHostIPv6Address -> Ordering
NodeHostIPv6Address -> NodeHostIPv6Address -> NodeHostIPv6Address
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NodeHostIPv6Address -> NodeHostIPv6Address -> NodeHostIPv6Address
$cmin :: NodeHostIPv6Address -> NodeHostIPv6Address -> NodeHostIPv6Address
max :: NodeHostIPv6Address -> NodeHostIPv6Address -> NodeHostIPv6Address
$cmax :: NodeHostIPv6Address -> NodeHostIPv6Address -> NodeHostIPv6Address
>= :: NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
$c>= :: NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
> :: NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
$c> :: NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
<= :: NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
$c<= :: NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
< :: NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
$c< :: NodeHostIPv6Address -> NodeHostIPv6Address -> Bool
compare :: NodeHostIPv6Address -> NodeHostIPv6Address -> Ordering
$ccompare :: NodeHostIPv6Address -> NodeHostIPv6Address -> Ordering
$cp1Ord :: Eq NodeHostIPv6Address
Ord)

instance FromJSON NodeHostIPv6Address where
  parseJSON :: Value -> Parser NodeHostIPv6Address
parseJSON (String Text
ipStr) =
    case String -> Maybe IPv6
forall a. Read a => String -> Maybe a
readMaybe (String -> Maybe IPv6) -> String -> Maybe IPv6
forall a b. (a -> b) -> a -> b
$ Text -> String
Text.unpack Text
ipStr of
      Just IPv6
ip -> NodeHostIPv6Address -> Parser NodeHostIPv6Address
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NodeHostIPv6Address -> Parser NodeHostIPv6Address)
-> NodeHostIPv6Address -> Parser NodeHostIPv6Address
forall a b. (a -> b) -> a -> b
$ IPv6 -> NodeHostIPv6Address
NodeHostIPv6Address IPv6
ip
      Maybe IPv6
Nothing -> String -> Parser NodeHostIPv6Address
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser NodeHostIPv6Address)
-> String -> Parser NodeHostIPv6Address
forall a b. (a -> b) -> a -> b
$ String
"Parsing of IPv6 failed: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
Text.unpack Text
ipStr
  parseJSON Value
invalid = String -> Parser NodeHostIPv6Address
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser NodeHostIPv6Address)
-> String -> Parser NodeHostIPv6Address
forall a b. (a -> b) -> a -> b
$ String
"Parsing of IPv6 failed due to type mismatch. "
                          String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"Encountered: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Value -> String
forall a b. (Show a, ConvertText String b) => a -> b
show Value
invalid String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"\n"
instance ToJSON NodeHostIPv6Address where
  toJSON :: NodeHostIPv6Address -> Value
toJSON (NodeHostIPv6Address IPv6
ip) = Text -> Value
String (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ IPv6 -> String
forall a b. (Show a, ConvertText String b) => a -> b
show IPv6
ip)


newtype NodeHostIPAddress
  = NodeHostIPAddress { NodeHostIPAddress -> IP
unNodeHostIPAddress :: IP }
  deriving newtype Int -> NodeHostIPAddress -> ShowS
[NodeHostIPAddress] -> ShowS
NodeHostIPAddress -> String
(Int -> NodeHostIPAddress -> ShowS)
-> (NodeHostIPAddress -> String)
-> ([NodeHostIPAddress] -> ShowS)
-> Show NodeHostIPAddress
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NodeHostIPAddress] -> ShowS
$cshowList :: [NodeHostIPAddress] -> ShowS
show :: NodeHostIPAddress -> String
$cshow :: NodeHostIPAddress -> String
showsPrec :: Int -> NodeHostIPAddress -> ShowS
$cshowsPrec :: Int -> NodeHostIPAddress -> ShowS
Show
  deriving (NodeHostIPAddress -> NodeHostIPAddress -> Bool
(NodeHostIPAddress -> NodeHostIPAddress -> Bool)
-> (NodeHostIPAddress -> NodeHostIPAddress -> Bool)
-> Eq NodeHostIPAddress
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NodeHostIPAddress -> NodeHostIPAddress -> Bool
$c/= :: NodeHostIPAddress -> NodeHostIPAddress -> Bool
== :: NodeHostIPAddress -> NodeHostIPAddress -> Bool
$c== :: NodeHostIPAddress -> NodeHostIPAddress -> Bool
Eq, Eq NodeHostIPAddress
Eq NodeHostIPAddress
-> (NodeHostIPAddress -> NodeHostIPAddress -> Ordering)
-> (NodeHostIPAddress -> NodeHostIPAddress -> Bool)
-> (NodeHostIPAddress -> NodeHostIPAddress -> Bool)
-> (NodeHostIPAddress -> NodeHostIPAddress -> Bool)
-> (NodeHostIPAddress -> NodeHostIPAddress -> Bool)
-> (NodeHostIPAddress -> NodeHostIPAddress -> NodeHostIPAddress)
-> (NodeHostIPAddress -> NodeHostIPAddress -> NodeHostIPAddress)
-> Ord NodeHostIPAddress
NodeHostIPAddress -> NodeHostIPAddress -> Bool
NodeHostIPAddress -> NodeHostIPAddress -> Ordering
NodeHostIPAddress -> NodeHostIPAddress -> NodeHostIPAddress
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NodeHostIPAddress -> NodeHostIPAddress -> NodeHostIPAddress
$cmin :: NodeHostIPAddress -> NodeHostIPAddress -> NodeHostIPAddress
max :: NodeHostIPAddress -> NodeHostIPAddress -> NodeHostIPAddress
$cmax :: NodeHostIPAddress -> NodeHostIPAddress -> NodeHostIPAddress
>= :: NodeHostIPAddress -> NodeHostIPAddress -> Bool
$c>= :: NodeHostIPAddress -> NodeHostIPAddress -> Bool
> :: NodeHostIPAddress -> NodeHostIPAddress -> Bool
$c> :: NodeHostIPAddress -> NodeHostIPAddress -> Bool
<= :: NodeHostIPAddress -> NodeHostIPAddress -> Bool
$c<= :: NodeHostIPAddress -> NodeHostIPAddress -> Bool
< :: NodeHostIPAddress -> NodeHostIPAddress -> Bool
$c< :: NodeHostIPAddress -> NodeHostIPAddress -> Bool
compare :: NodeHostIPAddress -> NodeHostIPAddress -> Ordering
$ccompare :: NodeHostIPAddress -> NodeHostIPAddress -> Ordering
$cp1Ord :: Eq NodeHostIPAddress
Ord)

instance FromJSON NodeHostIPAddress where
  parseJSON :: Value -> Parser NodeHostIPAddress
parseJSON (String Text
ipStr) =
    case String -> Maybe IP
forall a. Read a => String -> Maybe a
readMaybe (String -> Maybe IP) -> String -> Maybe IP
forall a b. (a -> b) -> a -> b
$ Text -> String
Text.unpack Text
ipStr of
      Just IP
ip -> NodeHostIPAddress -> Parser NodeHostIPAddress
forall (f :: * -> *) a. Applicative f => a -> f a
pure (NodeHostIPAddress -> Parser NodeHostIPAddress)
-> NodeHostIPAddress -> Parser NodeHostIPAddress
forall a b. (a -> b) -> a -> b
$ IP -> NodeHostIPAddress
NodeHostIPAddress IP
ip
      Maybe IP
Nothing -> String -> Parser NodeHostIPAddress
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser NodeHostIPAddress)
-> String -> Parser NodeHostIPAddress
forall a b. (a -> b) -> a -> b
$ String
"Parsing of IP failed: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
Text.unpack Text
ipStr
  parseJSON Value
invalid = String -> Parser NodeHostIPAddress
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser NodeHostIPAddress)
-> String -> Parser NodeHostIPAddress
forall a b. (a -> b) -> a -> b
$ String
"Parsing of IP failed due to type mismatch. "
                          String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"Encountered: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Value -> String
forall a b. (Show a, ConvertText String b) => a -> b
show Value
invalid String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"\n"

instance ToJSON NodeHostIPAddress where
  toJSON :: NodeHostIPAddress -> Value
toJSON (NodeHostIPAddress IP
ip) = Text -> Value
String (String -> Text
Text.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ IP -> String
forall a b. (Show a, ConvertText String b) => a -> b
show IP
ip)

nodeHostIPv6AddressToIPAddress :: NodeHostIPv6Address -> NodeHostIPAddress
nodeHostIPv6AddressToIPAddress :: NodeHostIPv6Address -> NodeHostIPAddress
nodeHostIPv6AddressToIPAddress (NodeHostIPv6Address IPv6
ip) = IP -> NodeHostIPAddress
NodeHostIPAddress (IPv6 -> IP
IPv6 IPv6
ip)

nodeHostIPv4AddressToIPAddress :: NodeHostIPv4Address -> NodeHostIPAddress
nodeHostIPv4AddressToIPAddress :: NodeHostIPv4Address -> NodeHostIPAddress
nodeHostIPv4AddressToIPAddress (NodeHostIPv4Address IPv4
ip) = IP -> NodeHostIPAddress
NodeHostIPAddress (IPv4 -> IP
IPv4 IPv4
ip)


-- | Domain name.
--
newtype NodeHostDnsAddress
  = NodeHostDnsAddress { NodeHostDnsAddress -> Text
unNodeHostDnsAddress :: Text }
  deriving newtype Int -> NodeHostDnsAddress -> ShowS
[NodeHostDnsAddress] -> ShowS
NodeHostDnsAddress -> String
(Int -> NodeHostDnsAddress -> ShowS)
-> (NodeHostDnsAddress -> String)
-> ([NodeHostDnsAddress] -> ShowS)
-> Show NodeHostDnsAddress
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NodeHostDnsAddress] -> ShowS
$cshowList :: [NodeHostDnsAddress] -> ShowS
show :: NodeHostDnsAddress -> String
$cshow :: NodeHostDnsAddress -> String
showsPrec :: Int -> NodeHostDnsAddress -> ShowS
$cshowsPrec :: Int -> NodeHostDnsAddress -> ShowS
Show
  deriving (NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
(NodeHostDnsAddress -> NodeHostDnsAddress -> Bool)
-> (NodeHostDnsAddress -> NodeHostDnsAddress -> Bool)
-> Eq NodeHostDnsAddress
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
$c/= :: NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
== :: NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
$c== :: NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
Eq, Eq NodeHostDnsAddress
Eq NodeHostDnsAddress
-> (NodeHostDnsAddress -> NodeHostDnsAddress -> Ordering)
-> (NodeHostDnsAddress -> NodeHostDnsAddress -> Bool)
-> (NodeHostDnsAddress -> NodeHostDnsAddress -> Bool)
-> (NodeHostDnsAddress -> NodeHostDnsAddress -> Bool)
-> (NodeHostDnsAddress -> NodeHostDnsAddress -> Bool)
-> (NodeHostDnsAddress -> NodeHostDnsAddress -> NodeHostDnsAddress)
-> (NodeHostDnsAddress -> NodeHostDnsAddress -> NodeHostDnsAddress)
-> Ord NodeHostDnsAddress
NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
NodeHostDnsAddress -> NodeHostDnsAddress -> Ordering
NodeHostDnsAddress -> NodeHostDnsAddress -> NodeHostDnsAddress
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: NodeHostDnsAddress -> NodeHostDnsAddress -> NodeHostDnsAddress
$cmin :: NodeHostDnsAddress -> NodeHostDnsAddress -> NodeHostDnsAddress
max :: NodeHostDnsAddress -> NodeHostDnsAddress -> NodeHostDnsAddress
$cmax :: NodeHostDnsAddress -> NodeHostDnsAddress -> NodeHostDnsAddress
>= :: NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
$c>= :: NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
> :: NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
$c> :: NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
<= :: NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
$c<= :: NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
< :: NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
$c< :: NodeHostDnsAddress -> NodeHostDnsAddress -> Bool
compare :: NodeHostDnsAddress -> NodeHostDnsAddress -> Ordering
$ccompare :: NodeHostDnsAddress -> NodeHostDnsAddress -> Ordering
$cp1Ord :: Eq NodeHostDnsAddress
Ord)

nodeHostDnsAddressToDomain :: NodeHostDnsAddress -> DNS.Domain
nodeHostDnsAddressToDomain :: NodeHostDnsAddress -> Domain
nodeHostDnsAddressToDomain = Text -> Domain
Text.encodeUtf8 (Text -> Domain)
-> (NodeHostDnsAddress -> Text) -> NodeHostDnsAddress -> Domain
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. NodeHostDnsAddress -> Text
unNodeHostDnsAddress


-- | Socket path
--
newtype SocketPath = SocketPath
  { SocketPath -> String
unSocketPath :: FilePath }
  deriving stock (SocketPath -> SocketPath -> Bool
(SocketPath -> SocketPath -> Bool)
-> (SocketPath -> SocketPath -> Bool) -> Eq SocketPath
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SocketPath -> SocketPath -> Bool
$c/= :: SocketPath -> SocketPath -> Bool
== :: SocketPath -> SocketPath -> Bool
$c== :: SocketPath -> SocketPath -> Bool
Eq, Eq SocketPath
Eq SocketPath
-> (SocketPath -> SocketPath -> Ordering)
-> (SocketPath -> SocketPath -> Bool)
-> (SocketPath -> SocketPath -> Bool)
-> (SocketPath -> SocketPath -> Bool)
-> (SocketPath -> SocketPath -> Bool)
-> (SocketPath -> SocketPath -> SocketPath)
-> (SocketPath -> SocketPath -> SocketPath)
-> Ord SocketPath
SocketPath -> SocketPath -> Bool
SocketPath -> SocketPath -> Ordering
SocketPath -> SocketPath -> SocketPath
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SocketPath -> SocketPath -> SocketPath
$cmin :: SocketPath -> SocketPath -> SocketPath
max :: SocketPath -> SocketPath -> SocketPath
$cmax :: SocketPath -> SocketPath -> SocketPath
>= :: SocketPath -> SocketPath -> Bool
$c>= :: SocketPath -> SocketPath -> Bool
> :: SocketPath -> SocketPath -> Bool
$c> :: SocketPath -> SocketPath -> Bool
<= :: SocketPath -> SocketPath -> Bool
$c<= :: SocketPath -> SocketPath -> Bool
< :: SocketPath -> SocketPath -> Bool
$c< :: SocketPath -> SocketPath -> Bool
compare :: SocketPath -> SocketPath -> Ordering
$ccompare :: SocketPath -> SocketPath -> Ordering
$cp1Ord :: Eq SocketPath
Ord)
  deriving newtype (Value -> Parser [SocketPath]
Value -> Parser SocketPath
(Value -> Parser SocketPath)
-> (Value -> Parser [SocketPath]) -> FromJSON SocketPath
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [SocketPath]
$cparseJSONList :: Value -> Parser [SocketPath]
parseJSON :: Value -> Parser SocketPath
$cparseJSON :: Value -> Parser SocketPath
FromJSON, String -> SocketPath
(String -> SocketPath) -> IsString SocketPath
forall a. (String -> a) -> IsString a
fromString :: String -> SocketPath
$cfromString :: String -> SocketPath
IsString, Int -> SocketPath -> ShowS
[SocketPath] -> ShowS
SocketPath -> String
(Int -> SocketPath -> ShowS)
-> (SocketPath -> String)
-> ([SocketPath] -> ShowS)
-> Show SocketPath
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SocketPath] -> ShowS
$cshowList :: [SocketPath] -> ShowS
show :: SocketPath -> String
$cshow :: SocketPath -> String
showsPrec :: Int -> SocketPath -> ShowS
$cshowsPrec :: Int -> SocketPath -> ShowS
Show)