module Database.PostgreSQL.Printer
       ( Printer, execPrinter
       , v4HostAddress
       , v6HostAddress
       , netAddress
       ) where

import Numeric (showInt, showHex)

import Text.Printer.List (token, list, execPrinter)
import qualified Text.Printer.List as P
import Data.PostgreSQL.NetworkAddress
  (V4HostAddress, v4HostAddressOctets, V6HostAddress, v6HostAddressWords, NetAddress (..))


type Printer a = P.Printer Char a
type PrintM = P.PrintM Char


mapShowS :: (a -> ShowS) -> Printer a
mapShowS :: (a -> ShowS) -> Printer a
mapShowS s :: a -> ShowS
s = Printer Char [Char]
forall t. Printer t [t]
list Printer Char [Char] -> (a -> [Char]) -> Printer a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ []) (ShowS -> [Char]) -> (a -> ShowS) -> a -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ShowS
s

dec :: (Integral a, Show a) => Printer a
dec :: Printer a
dec = (a -> ShowS) -> Printer a
forall a. (a -> ShowS) -> Printer a
mapShowS a -> ShowS
forall a. Integral a => a -> ShowS
showInt

hex :: (Integral a, Show a) => Printer a
hex :: Printer a
hex = (a -> ShowS) -> Printer a
forall a. (a -> ShowS) -> Printer a
mapShowS a -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex

dot :: PrintM ()
dot :: PrintM ()
dot = Printer Char Char
forall t. Printer t t
token '.'

colon :: PrintM ()
colon :: PrintM ()
colon = Printer Char Char
forall t. Printer t t
token ':'

slash :: PrintM ()
slash :: PrintM ()
slash = Printer Char Char
forall t. Printer t t
token '/'

v4HostAddress :: Printer V4HostAddress
v4HostAddress :: Printer V4HostAddress
v4HostAddress ha :: V4HostAddress
ha = do
  let (a :: Word8
a, b :: Word8
b, c :: Word8
c, d :: Word8
d) = V4HostAddress -> (Word8, Word8, Word8, Word8)
v4HostAddressOctets V4HostAddress
ha
  Printer Word8
forall a. (Integral a, Show a) => Printer a
dec Word8
a
  PrintM ()
dot
  Printer Word8
forall a. (Integral a, Show a) => Printer a
dec Word8
b
  PrintM ()
dot
  Printer Word8
forall a. (Integral a, Show a) => Printer a
dec Word8
c
  PrintM ()
dot
  Printer Word8
forall a. (Integral a, Show a) => Printer a
dec Word8
d

v6HostAddress :: Printer V6HostAddress
v6HostAddress :: Printer V6HostAddress
v6HostAddress ha :: V6HostAddress
ha = do
  let (a :: Word16
a, b :: Word16
b, c :: Word16
c, d :: Word16
d, e :: Word16
e, f :: Word16
f, g :: Word16
g, h :: Word16
h) = V6HostAddress
-> (Word16, Word16, Word16, Word16, Word16, Word16, Word16, Word16)
v6HostAddressWords V6HostAddress
ha
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
a
  PrintM ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
b
  PrintM ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
c
  PrintM ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
d
  PrintM ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
e
  PrintM ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
f
  PrintM ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
g
  PrintM ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
h

netAddress :: Printer NetAddress
netAddress :: Printer NetAddress
netAddress = Printer NetAddress
d  where
  d :: Printer NetAddress
d (NetAddress4 ha :: V4HostAddress
ha m :: Word8
m) = do
    Printer V4HostAddress
v4HostAddress V4HostAddress
ha
    PrintM ()
slash
    Printer Word8
forall a. (Integral a, Show a) => Printer a
dec Word8
m
  d (NetAddress6 v6 :: V6HostAddress
v6 m :: Word8
m) = do
    Printer V6HostAddress
v6HostAddress V6HostAddress
v6
    PrintM ()
slash
    Printer Word8
forall a. (Integral a, Show a) => Printer a
dec Word8
m