content: -----------------------------------------------------------------------------
  -- |
  -- Copyright   : (c) 2012 
  -- License     : BSD-style
  -- Maintainer  : florbitous@gmail.com
  -- Stability   : experimental
  -- Portability : ghc
  --
  -- Pretty printing utilities.
  --
  -----------------------------------------------------------------------------
  
  module Blip.Pretty
     ( Pretty (..)
     , prettyString
     , prettyList
     , prettyTuple
     , showBits
     ) where
  
  import Prelude hiding ((<>))
  import Data.Word (Word64, Word32, Word16, Word8)
  import Text.PrettyPrint
  import Data.ByteString.Lazy (ByteString)
  import Data.ByteString.Lazy.Char8 (unpack)
  import Data.Bits (testBit, Bits, bitSize)
  
  -- -----------------------------------------------------------------------------
  
  -- | Pretty printing interface.
  class Pretty a where
     -- ^ Generate a document for a value.
     pretty :: a -> Doc
  
  prettyList :: [Doc] -> Doc
  prettyList = brackets . hcat . punctuate comma
  
  prettyTuple :: [Doc] -> Doc
  prettyTuple = parens . hcat . punctuate comma
  
  -- | Render an instance of "Pretty" as a "String".
  prettyString :: Pretty a => a -> String
  prettyString = render . pretty
  
  instance Pretty a => Pretty (Maybe a) where
     pretty Nothing = empty
     pretty (Just x) = pretty x
  
  instance Pretty Word8 where
     pretty = integer . fromIntegral
  
  instance Pretty Word16 where
     pretty = integer . fromIntegral
  
  instance Pretty Word32 where
     pretty = integer . fromIntegral
  
  instance Pretty Word64 where
     pretty = integer . fromIntegral
  
  instance Pretty Int where
     pretty = int
  
  instance Pretty Integer where
     pretty = integer 
  
  instance Pretty Double where
     pretty = double
  
  instance (Pretty a, Pretty b) => Pretty (a, b) where
     pretty (x, y) = text "(" <> pretty x <> text ", " <> pretty y <> text ")"
  
  instance Pretty ByteString where
     pretty = text . unpack
  
  -- | Render an instance of "Bits" as a list of "Bool", where "True" represents the high bit and "False" represents the low bit.
  bits :: Bits a => a -> [Bool]
  bits x = map (testBit x) [0 .. bitSize x - 1]
  
  -- | Render an instance of "Bits" as a "String". 
  showBits :: Bits a => a -> String
  showBits = map toBit . bits
     where
     toBit True  = '1'
     toBit False = '0'
  