{-# LANGUAGE DeriveDataTypeable #-}

module Data.EDN.AST.Types.Value
  ( TaggedValue
  , Value(..)
  , EDNList
  , EDNVec
  , EDNMap
  , EDNSet
  , mkList
  , mkVec
  , mkMap
  , mkSet
  ) where

import Data.Data (Data)
import Data.Foldable (toList)
import Data.Text (Text)

import qualified Data.Vector as V
import qualified Data.Map.Strict as M
import qualified Data.Set as S

import Data.EDN.AST.Types.Tagged (Tagged)

type TaggedValue = Tagged Text Value

data Value
  = Nil
  | Boolean   !Bool
  | String    !Text
  | Character !Char
  | Symbol    !Text !Text
  | Keyword   !Text
  | Integer   !Int
  | Floating  !Double
  | List      !EDNList
  | Vec       !EDNVec
  | Map       !EDNMap
  | Set       !EDNSet
  deriving (Eq, Ord, Show, Data)

type EDNList = [TaggedValue]
type EDNVec  = V.Vector TaggedValue
type EDNMap  = M.Map TaggedValue TaggedValue
type EDNSet  = S.Set TaggedValue

mkList :: Foldable f => f TaggedValue -> Value
mkList = List . toList

mkVec :: Foldable f => f TaggedValue -> Value
mkVec = Vec . V.fromList . toList

mkMap :: Foldable f => f (TaggedValue, TaggedValue) -> Value
mkMap = Map . M.fromList . toList

mkSet :: Foldable f => f TaggedValue -> Value
mkSet = Set . S.fromList . toList