packages feed

rel8-1.7.0.0: src/Rel8/Type/Name.hs

{-# language RecordWildCards #-}
{-# language StrictData #-}

module Rel8.Type.Name
  ( TypeName (..)
  , showTypeName
  )
where

-- base
import Data.Semigroup (mtimesDefault)
import Data.String (IsString, fromString)
import Prelude

-- pretty
import Text.PrettyPrint (Doc, comma, hcat, parens, punctuate, text)

-- rel8
import Rel8.Schema.QualifiedName (QualifiedName, ppQualifiedName)


-- | A PostgreSQL type consists of a 'QualifiedName' (name, schema), and
-- optional 'modifiers' and 'arrayDepth'. 'modifiers' will usually be @[]@,
-- but a type like @numeric(6, 2)@ will have @["6", "2"]@. 'arrayDepth' is
-- always @0@ for non-array types.
data TypeName = TypeName
  { name :: QualifiedName
    -- ^ The name (and schema) of the type.
  , modifiers :: [String]
    -- ^ Any modifiers applied to the underlying type.
  , arrayDepth :: Word
    -- ^ If this is an array type, the depth of that array (@1@ for @[]@, @2@
    -- for @[][]@, etc).
  }


-- | Constructs 'TypeName's with 'schema' set to 'Nothing', 'modifiers' set
-- to @[]@ and 'arrayDepth' set to @0@.
instance IsString TypeName where
  fromString string =
    TypeName
      { name = fromString string
      , modifiers = []
      , arrayDepth = 0
      }


ppTypeName :: TypeName -> Doc
ppTypeName TypeName {..} =
  ppQualifiedName name <> modifier <> mtimesDefault arrayDepth (text "[]")
  where
    modifier
      | null modifiers = mempty
      | otherwise = parens (hcat $ punctuate comma $ text <$> modifiers)


showTypeName :: TypeName -> String
showTypeName = show . ppTypeName