{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE PolyKinds #-} -- removes need to annotate kinds as [Symbol]
{-# LANGUAGE FlexibleContexts #-}

-- | Text encoding combinators specific to 'T.Text'
-- @since 0.2.2.0
module Data.TypedEncoding.Conv.Text where

import qualified Data.Text as T
import qualified Data.TypedEncoding.Common.Util.TypeLits as Knds
import           Data.TypedEncoding.Instances.Support


-- $setup
-- >>> :set -XDataKinds -XTypeFamilies -XTypeApplications


-- | This assumes that each of the encodings in @xs@ work work equivalently in @String@ and @Text@.
-- See discussion in "Examples.TypedEncoding.Conversions" and 
-- "Data.TypedEncoding.Conv.ByteString.Char8.pack"
pack :: (
          Knds.UnSnoc xs ~ '(,) ys y
         , Superset "r-UNICODE.D76" y 
         , encs ~ RemoveRs ys
         , AllEncodeInto "r-UNICODE.D76" encs
          ) => Enc xs c String -> Enc xs c T.Text
pack :: Enc @[Symbol] xs c String -> Enc @[Symbol] xs c Text
pack = (String -> Text)
-> Enc @[Symbol] xs c String -> Enc @[Symbol] xs c Text
forall k s1 s2 (e :: k) c.
(s1 -> s2) -> Enc @k e c s1 -> Enc @k e c s2
unsafeChangePayload String -> Text
T.pack

-- | simplified version of @pack@ that works on single /r-/ encodings
-- @since 0.5.2.0
pack1 :: (
         Superset "r-UNICODE.D76" y 
         ) => Enc '[y] c String -> Enc '[y] c T.Text
pack1 :: Enc @[Symbol] ((':) @Symbol y ('[] @Symbol)) c String
-> Enc @[Symbol] ((':) @Symbol y ('[] @Symbol)) c Text
pack1 = Enc @[Symbol] ((':) @Symbol y ('[] @Symbol)) c String
-> Enc @[Symbol] ((':) @Symbol y ('[] @Symbol)) c Text
forall (xs :: [Symbol]) (ys :: [Symbol]) (y :: Symbol)
       (encs :: [Symbol]) c.
((UnSnoc @Symbol xs :: ([Symbol], Symbol))
 ~ ('(ys, y) :: ([Symbol], Symbol)),
 Superset "r-UNICODE.D76" y,
 (encs :: [Symbol]) ~ (RemoveRs ys :: [Symbol]),
 AllEncodeInto "r-UNICODE.D76" encs) =>
Enc @[Symbol] xs c String -> Enc @[Symbol] xs c Text
pack

-- | This assumes that each of the encodings in @xs@ work work equivalently in @String@ and @Text@.
-- This is similar to the assumptions made in 'pack'. 
unpack :: (
          Knds.UnSnoc xs ~ '(,) ys y
         , Superset "r-UNICODE.D76" y 
         , encs ~ RemoveRs ys
         , AllEncodeInto "r-UNICODE.D76" encs
          ) => Enc xs c T.Text -> Enc xs c String
unpack :: Enc @[Symbol] xs c Text -> Enc @[Symbol] xs c String
unpack = (Text -> String)
-> Enc @[Symbol] xs c Text -> Enc @[Symbol] xs c String
forall k s1 s2 (e :: k) c.
(s1 -> s2) -> Enc @k e c s1 -> Enc @k e c s2
unsafeChangePayload Text -> String
T.unpack 

-- | simplified version of @unpack@ that works on single /r-/ encodings
-- @since 0.5.2.0
unpack1 :: (
         Superset "r-UNICODE.D76" y 
         ) => Enc '[y] c T.Text -> Enc '[y] c String
unpack1 :: Enc @[Symbol] ((':) @Symbol y ('[] @Symbol)) c Text
-> Enc @[Symbol] ((':) @Symbol y ('[] @Symbol)) c String
unpack1 = Enc @[Symbol] ((':) @Symbol y ('[] @Symbol)) c Text
-> Enc @[Symbol] ((':) @Symbol y ('[] @Symbol)) c String
forall (xs :: [Symbol]) (ys :: [Symbol]) (y :: Symbol)
       (encs :: [Symbol]) c.
((UnSnoc @Symbol xs :: ([Symbol], Symbol))
 ~ ('(ys, y) :: ([Symbol], Symbol)),
 Superset "r-UNICODE.D76" y,
 (encs :: [Symbol]) ~ (RemoveRs ys :: [Symbol]),
 AllEncodeInto "r-UNICODE.D76" encs) =>
Enc @[Symbol] xs c Text -> Enc @[Symbol] xs c String
unpack

-- | 
-- Text is automatically @"r-UTF8"@ encoded
-- 
-- Adding @"r-UTF8"@ annotation simply adds type level interpretion requirement that 'T.Text' is treated
-- as /UTF8/. The internals of 'T.Text' (currently /UTF-16/) are not relevant and @utf8Promote@ is implemented
-- as 'id'.  This is not the same as encoding @Word8@ layouts into 'Char'-s.
-- This, in /typed-encoding/ terminology, would be @"enc-UTF8"@, not @"r-UTF8".
--
-- >>> displ $ utf8Promote $ toEncoding () ("text" :: T.Text)
-- "Enc '[r-UTF8] () (Text text)"
utf8Promote :: Enc xs c T.Text -> Enc (Snoc xs "r-UTF8") c T.Text
utf8Promote :: Enc @[Symbol] xs c Text
-> Enc @[Symbol] (Snoc @Symbol xs "r-UTF8") c Text
utf8Promote = (Text -> Text)
-> Enc @[Symbol] xs c Text
-> Enc @[Symbol] (Snoc @Symbol xs "r-UTF8") c Text
forall k1 k2 s1 s2 (e1 :: k1) c (e2 :: k2).
(s1 -> s2) -> Enc @k1 e1 c s1 -> Enc @k2 e2 c s2
withUnsafeCoerce Text -> Text
forall a. a -> a
id

-- | 
-- For 'T.Text' @"r-UTF8"@ is redundant
--
-- >>> displ . utf8Demote $ (unsafeSetPayload () "Hello" :: Enc '["r-UTF8"] () T.Text)
-- "Enc '[] () (Text Hello)"
utf8Demote :: (UnSnoc xs ~ '(,) ys "r-UTF8") => Enc xs c T.Text -> Enc ys c T.Text
utf8Demote :: Enc @[Symbol] xs c Text -> Enc @[Symbol] ys c Text
utf8Demote = (Text -> Text)
-> Enc @[Symbol] xs c Text -> Enc @[Symbol] ys c Text
forall k1 k2 s1 s2 (e1 :: k1) c (e2 :: k2).
(s1 -> s2) -> Enc @k1 e1 c s1 -> Enc @k2 e2 c s2
withUnsafeCoerce Text -> Text
forall a. a -> a
id


d76Promote :: Enc xs c T.Text -> Enc (Snoc xs "r-UNICODE.D76") c T.Text
d76Promote :: Enc @[Symbol] xs c Text
-> Enc @[Symbol] (Snoc @Symbol xs "r-UNICODE.D76") c Text
d76Promote = (Text -> Text)
-> Enc @[Symbol] xs c Text
-> Enc @[Symbol] (Snoc @Symbol xs "r-UNICODE.D76") c Text
forall k1 k2 s1 s2 (e1 :: k1) c (e2 :: k2).
(s1 -> s2) -> Enc @k1 e1 c s1 -> Enc @k2 e2 c s2
withUnsafeCoerce Text -> Text
forall a. a -> a
id

d76Demote :: (UnSnoc xs ~ '(,) ys "r-UNICODE.D76") => Enc xs c T.Text -> Enc ys c T.Text
d76Demote :: Enc @[Symbol] xs c Text -> Enc @[Symbol] ys c Text
d76Demote = (Text -> Text)
-> Enc @[Symbol] xs c Text -> Enc @[Symbol] ys c Text
forall k1 k2 s1 s2 (e1 :: k1) c (e2 :: k2).
(s1 -> s2) -> Enc @k1 e1 c s1 -> Enc @k2 e2 c s2
withUnsafeCoerce Text -> Text
forall a. a -> a
id