content: {-# LANGUAGE GeneralizedNewtypeDeriving #-}
  {-# LANGUAGE OverloadedStrings #-}
  
  module Eventful.Store.Sql.JSONString
    ( JSONString
    , jsonStringSerializer
    ) where
  
  import Data.Aeson
  import Data.Text.Lazy (Text)
  import qualified Data.Text.Lazy.Encoding as TLE
  import Database.Persist
  import Database.Persist.Sql
  
  import Eventful.Serializer
  
  -- | A more specific type than just ByteString for JSON data.
  newtype JSONString = JSONString { unJSONString :: Text }
    deriving (Eq, PersistField)
  
  instance PersistFieldSql JSONString where
    sqlType _ = SqlOther "jsonb"
  
  instance Show JSONString where
    show = show . unJSONString
  
  jsonStringSerializer :: (ToJSON a, FromJSON a) => Serializer a JSONString
  jsonStringSerializer =
    Serializer
    encodeJSON
    decodeJSON
    decodeJSONEither
  
  encodeJSON :: (ToJSON a) => a -> JSONString
  encodeJSON = JSONString . TLE.decodeUtf8 . encode
  
  decodeJSON :: (FromJSON a) => JSONString -> Maybe a
  decodeJSON = decode . TLE.encodeUtf8 . unJSONString
  
  decodeJSONEither :: (FromJSON a) => JSONString -> Either String a
  decodeJSONEither = eitherDecode . TLE.encodeUtf8 . unJSONString
  