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 :: forall a. (a -> ShowS) -> Printer a
mapShowS a -> ShowS
s = Printer Char [Char]
forall t. Printer t [t]
list Printer Char [Char] -> (a -> [Char]) -> a -> PrintM Char ()
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 :: forall a. (Integral a, Show a) => 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 :: forall a. (Integral a, Show a) => Printer a
hex = (a -> ShowS) -> Printer a
forall a. (a -> ShowS) -> Printer a
mapShowS a -> ShowS
forall a. Integral a => a -> ShowS
showHex

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

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

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

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

v6HostAddress :: Printer V6HostAddress
v6HostAddress :: Printer V6HostAddress
v6HostAddress V6HostAddress
ha = do
  let (Word16
a, Word16
b, Word16
c, Word16
d, Word16
e, Word16
f, Word16
g, 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 Char ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
b
  PrintM Char ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
c
  PrintM Char ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
d
  PrintM Char ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
e
  PrintM Char ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
f
  PrintM Char ()
colon
  Printer Word16
forall a. (Integral a, Show a) => Printer a
hex Word16
g
  PrintM Char ()
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 V4HostAddress
ha Word8
m) = do
    Printer V4HostAddress
v4HostAddress V4HostAddress
ha
    PrintM Char ()
slash
    Printer Word8
forall a. (Integral a, Show a) => Printer a
dec Word8
m
  d (NetAddress6 V6HostAddress
v6 Word8
m) = do
    Printer V6HostAddress
v6HostAddress V6HostAddress
v6
    PrintM Char ()
slash
    Printer Word8
forall a. (Integral a, Show a) => Printer a
dec Word8
m