{-# language MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances #-}

-- | A type class for converting strings.
-- Supported types are:
--
--     * 'String'
--
--     * strict 'Data.ByteString.ByteString'
--
--     * lazy 'Data.ByteString.Lazy.ByteString'
--
--     * strict 'Data.Text.Text'
--
--     * lazy 'Data.Text.Lazy.Text'
--
-- Assumes UTF-8.

module Data.String.Conversions where


import Data.Monoid

import Control.Applicative

-- string imports

import qualified Data.ByteString
import qualified Data.ByteString.UTF8

import qualified Data.ByteString.Lazy
import qualified Data.ByteString.Lazy.UTF8

import qualified Data.Text
import qualified Data.Text.Encoding

import qualified Data.Text.Lazy
import qualified Data.Text.Lazy.Encoding


-- * class and conversions

class ConvertibleStrings a b where
    convertString :: a -> b

cs :: ConvertibleStrings a b => a -> b
cs = convertString


-- * type synonyms

type StrictByteString = Data.ByteString.ByteString
type SBS              = Data.ByteString.ByteString

type LazyByteString = Data.ByteString.Lazy.ByteString
type LBS            = Data.ByteString.Lazy.ByteString

type StrictText = Data.Text.Text
type ST         = Data.Text.Text

type LazyText = Data.Text.Lazy.Text
type LT       = Data.Text.Lazy.Text


-- instances
-- ---------

-- from String

instance ConvertibleStrings String StrictByteString where
    convertString = Data.ByteString.UTF8.fromString

instance ConvertibleStrings String LazyByteString where
    convertString = Data.ByteString.Lazy.UTF8.fromString

instance ConvertibleStrings String StrictText where
    convertString = Data.Text.pack

instance ConvertibleStrings String LazyText where
    convertString = Data.Text.Lazy.pack


-- from StrictByteString

instance ConvertibleStrings StrictByteString String where
    convertString = Data.ByteString.UTF8.toString

instance ConvertibleStrings StrictByteString LazyByteString where
    convertString = Data.ByteString.Lazy.fromChunks . pure

instance ConvertibleStrings StrictByteString StrictText where
    convertString = Data.Text.Encoding.decodeUtf8

instance ConvertibleStrings StrictByteString LazyText where
    convertString =
        Data.Text.Lazy.Encoding.decodeUtf8 . Data.ByteString.Lazy.fromChunks . pure


-- from LazyByteString

instance ConvertibleStrings LazyByteString String where
    convertString = Data.ByteString.Lazy.UTF8.toString

instance ConvertibleStrings LazyByteString StrictByteString where
    convertString = mconcat . Data.ByteString.Lazy.toChunks

instance ConvertibleStrings LazyByteString StrictText where
    convertString = Data.Text.Encoding.decodeUtf8 . mconcat . Data.ByteString.Lazy.toChunks

instance ConvertibleStrings LazyByteString LazyText where
    convertString = Data.Text.Lazy.Encoding.decodeUtf8


-- from StrictText

instance ConvertibleStrings StrictText String where
    convertString = Data.Text.unpack

instance ConvertibleStrings StrictText StrictByteString where
    convertString = Data.Text.Encoding.encodeUtf8

instance ConvertibleStrings StrictText LazyByteString where
    convertString = Data.ByteString.Lazy.fromChunks . pure . Data.Text.Encoding.encodeUtf8

instance ConvertibleStrings StrictText LazyText where
    convertString = Data.Text.Lazy.fromChunks . pure


-- from LazyText

instance ConvertibleStrings LazyText String where
    convertString = Data.Text.Lazy.unpack

instance ConvertibleStrings LazyText StrictByteString where
    convertString =
        mconcat . Data.ByteString.Lazy.toChunks . Data.Text.Lazy.Encoding.encodeUtf8

instance ConvertibleStrings LazyText LazyByteString where
    convertString = Data.Text.Lazy.Encoding.encodeUtf8

instance ConvertibleStrings LazyText StrictText where
    convertString = mconcat . Data.Text.Lazy.toChunks