{-# LANGUAGE CPP               #-}
{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-|
Module:      TextShow.Data.Array
Copyright:   (C) 2014-2015 Ryan Scott
License:     BSD-style (see the file LICENSE)
Maintainer:  Ryan Scott
Stability:   Provisional
Portability: GHC

Monomorphic 'TextShow' function for 'Array' values.

/Since: 2/
-}
module TextShow.Data.Array (
      showbArrayPrec
    , showbUArrayPrec
    , showbIArrayPrec
    ) where

import qualified Data.Array as Array (assocs, bounds)
import           Data.Array (Array)
import qualified Data.Array.Base as IArray (assocs, bounds)
import           Data.Array.Base (IArray)
import           Data.Array.Unboxed (UArray)
import           Data.Ix (Ix)
import           Data.Monoid.Compat ((<>))
import           Data.Text.Lazy.Builder (Builder)

import           GHC.Show (appPrec)

import           Prelude ()
import           Prelude.Compat

import           TextShow.Classes (TextShow(showb, showbPrec), showbParen, showbSpace)
import           TextShow.Data.List ()
import           TextShow.Data.Tuple ()

#include "inline.h"

-- | Convert an 'Array' value to a 'Builder' with the given precedence.
--
-- /Since: 2/
showbArrayPrec :: (TextShow i, TextShow e, Ix i) => Int -> Array i e -> Builder
showbArrayPrec p a = showbParen (p > appPrec) $
       "array "
    <> showb (Array.bounds a)
    <> showbSpace
    <> showb (Array.assocs a)
{-# INLINE showbArrayPrec #-}

-- | Convert a 'UArray' value to a 'Builder' with the given precedence.
--
-- /Since: 2/
showbUArrayPrec :: (IArray UArray e, Ix i, TextShow i, TextShow e) => Int -> UArray i e -> Builder
showbUArrayPrec = showbIArrayPrec
{-# INLINE showbUArrayPrec #-}

{-# SPECIALIZE
    showbIArrayPrec :: (IArray UArray e, Ix i, TextShow i, TextShow e) =>
                        Int -> UArray i e -> Builder
  #-}
-- | Convert an 'IArray' instance to a 'Builder' with the given precedence.
--
-- /Since: 2/
showbIArrayPrec :: (IArray a e, Ix i, TextShow i, TextShow e) => Int -> a i e -> Builder
showbIArrayPrec p a = showbParen (p > 9) $
       "array "
    <> showb (IArray.bounds a)
    <> showbSpace
    <> showb (IArray.assocs a)

instance (TextShow i, TextShow e, Ix i) => TextShow (Array i e) where
    showbPrec = showbArrayPrec
    INLINE_INST_FUN(showbPrec)

instance (IArray UArray e, Ix i, TextShow i, TextShow e) => TextShow (UArray i e) where
    showbPrec = showbUArrayPrec
    INLINE_INST_FUN(showbPrec)
