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

Provides 'TextShow' instances for 'Array' types, as well as the
'showbIArrayPrec' function.

/Since: 2/
-}
module TextShow.Data.Array (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.Text.Lazy.Builder (Builder)

import           GHC.Show (appPrec)

import           Prelude ()
import           Prelude.Compat

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

{-# 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 :: forall (a :: * -> * -> *) e i.
(IArray a e, Ix i, TextShow i, TextShow e) =>
Int -> a i e -> Builder
showbIArrayPrec Int
p a i e
a = Bool -> Builder -> Builder
showbParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
arrayPrec) (Builder -> Builder) -> Builder -> Builder
forall a b. (a -> b) -> a -> b
$
       Builder
"array "
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (i, i) -> Builder
forall a. TextShow a => a -> Builder
showb (a i e -> (i, i)
forall i. Ix i => a i e -> (i, i)
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> (i, i)
IArray.bounds a i e
a)
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
showbSpace
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> [(i, e)] -> Builder
forall a. TextShow a => a -> Builder
showb (a i e -> [(i, e)]
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> [(i, e)]
IArray.assocs a i e
a)
  where
    arrayPrec :: Int
#if MIN_VERSION_base(4,13,0)
    arrayPrec :: Int
arrayPrec = Int
appPrec
#else
    arrayPrec = 9
#endif

-- | /Since: 2/
instance (TextShow i, TextShow e, Ix i) => TextShow (Array i e) where
    showbPrec :: Int -> Array i e -> Builder
showbPrec Int
p Array i e
a = Bool -> Builder -> Builder
showbParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
appPrec) (Builder -> Builder) -> Builder -> Builder
forall a b. (a -> b) -> a -> b
$
           Builder
"array "
        Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (i, i) -> Builder
forall a. TextShow a => a -> Builder
showb (Array i e -> (i, i)
forall i e. Array i e -> (i, i)
Array.bounds Array i e
a)
        Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
showbSpace
        Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> [(i, e)] -> Builder
forall a. TextShow a => a -> Builder
showb (Array i e -> [(i, e)]
forall i e. Ix i => Array i e -> [(i, e)]
Array.assocs Array i e
a)
    {-# INLINE showbPrec #-}

-- | /Since: 2/
instance (IArray UArray e, Ix i, TextShow i, TextShow e) => TextShow (UArray i e) where
    showbPrec :: Int -> UArray i e -> Builder
showbPrec = Int -> UArray i e -> Builder
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i, TextShow i, TextShow e) =>
Int -> a i e -> Builder
showbIArrayPrec
    {-# INLINE showbPrec #-}