packages feed

text-encode-0.1.0.0: src/text-encode-aeson/Text/Encode/Aeson.hs

module Text.Encode.Aeson (
  module Text.Encode,
  JsonEncode,
) where

import Text.Encode

import Data.Aeson (
  FromJSON (..),
  FromJSONKey (..),
  ToJSON (..),
  ToJSONKey (..),
  Value (..),
  eitherDecode,
  encode
 )
import Data.ByteString.Lazy.Char8 qualified as LC8
import Data.Coerce (coerce)
import Data.Text.Lazy qualified as LT
import Data.Text.Lazy.Encoding qualified as LTE
import Data.Typeable (Typeable)

instance (TextEncode a, Typeable a) => FromJSON (ViaTextEncode a) where
  parseJSON (String txt) = either fail pure $ decodeText txt
  parseJSON raw = fail $ typedError @a "parseJSON" "Expected String, got " $ encode raw

instance TextEncode a => ToJSON (ViaTextEncode a) where
  toJSON = String . encodeText
  toEncoding = toEncoding . encodeText

  {-# INLINE toJSON #-}
  {-# INLINE toEncoding #-}

instance (TextEncode a, Typeable a) => FromJSONKey (ViaTextEncode a)
instance TextEncode a => ToJSONKey (ViaTextEncode a)

data JsonEncode

instance (FromJSON a, ToJSON a) => TextEncode (DeriveTextEncode JsonEncode a) where
  encodeLazyByteString = coerce $ encode @a
  decodeLazyByteString = coerce $ eitherDecode @a
  encodeByteString = LC8.toStrict . encodeLazyByteString
  decodeByteString = decodeLazyByteString . LC8.fromStrict
  encodeString = LC8.unpack <$> encodeLazyByteString
  decodeString = decodeLazyByteString . LC8.pack
  encodeLazyText = LTE.decodeLatin1 . encodeLazyByteString
  decodeLazyText = decodeLazyByteString . LTE.encodeUtf8
  encodeText = LT.toStrict . encodeLazyText
  decodeText = decodeLazyText . LT.fromStrict

  {-# INLINE encodeLazyByteString #-}
  {-# INLINE decodeLazyByteString #-}
  {-# INLINE encodeByteString #-}
  {-# INLINE decodeByteString #-}
  {-# INLINE encodeString #-}
  {-# INLINE decodeString #-}
  {-# INLINE encodeLazyText #-}
  {-# INLINE decodeLazyText #-}
  {-# INLINE encodeText #-}
  {-# INLINE decodeText #-}