module Text.Str (
Str(..)
, IsString(..)
, show
, error
, joinLines
, joinCommas
, joinSemis
, joinSlashes
, asString
, asByteString
, asText
, asString2
, asByteString2
, wrapText
, wrapString
, wrapByteString
, wrapByteString2
, unlines
, putStrLn
) where
import qualified Prelude as P
import Prelude (IO, Show, String, Char, Bool, Int, Ord(..), (.), id, ($), flip)
import qualified Codec.Binary.UTF8.String as US
import Data.Char (isSpace, toLower, toUpper)
import Data.Hashable
import Data.Monoid
import Data.String (IsString(..))
import qualified Data.List as L
import qualified Data.List.Utils as L
import qualified Data.Text as T
import Data.Text (Text)
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
import qualified Data.ByteString.Char8 as BC
import qualified Data.ByteString as B
import qualified Data.ByteString.Base16 as B16
import Data.ByteString (ByteString)
import Codec.Utils (Octet)
class (IsString s, Show s, Ord s, Hashable s, Monoid s) => Str s where
toString :: s -> String
toByteString :: s -> ByteString
toText :: s -> Text
toOctets :: s -> [Octet]
toHex :: s -> s
toHex = asByteString B16.encode
fromText :: Text -> s
fromByteString :: ByteString -> s
fromOctets :: [Octet] -> s
joinBy :: s -> [s] -> s
splitOn :: s -> s -> [s]
smap :: (Char -> Char) -> s -> s
singleton :: Char -> s
cons :: Char -> s -> s
snoc :: s -> Char -> s
lower :: s -> s
lower = smap toLower
upper :: s -> s
upper = smap toUpper
capitalize :: s -> s
capitalize = asString $ \case
"" -> ""
(c:cs) -> toUpper c : cs
reverse :: s -> s
length :: s -> Int
dropWhile :: (Char -> Bool) -> s -> s
isPrefixOf :: s -> s -> Bool
isSuffixOf :: s -> s -> Bool
trim :: s -> s
trim = let f = reverse . dropWhile isSpace in f . f
instance Str String where
toString = id
toByteString = BC.pack
toText = T.pack
toOctets = US.encode
fromByteString = BC.unpack
fromText = T.unpack
fromOctets = US.decode
joinBy = L.intercalate
smap = P.map
splitOn = L.split
singleton c = [c]
cons = (:)
snoc s c = s <> [c]
reverse = P.reverse
dropWhile = P.dropWhile
isPrefixOf = L.isPrefixOf
isSuffixOf = L.isSuffixOf
length = L.length
instance Str ByteString where
toString = BC.unpack
toByteString = id
toText = decodeUtf8
toOctets = B.unpack
fromByteString = id
fromText = encodeUtf8
fromOctets = B.pack
smap = BC.map
joinBy = BC.intercalate
singleton = BC.singleton
splitOn = P.undefined
cons = BC.cons
snoc = BC.snoc
reverse = BC.reverse
dropWhile = BC.dropWhile
isPrefixOf = B.isPrefixOf
isSuffixOf = B.isSuffixOf
length = B.length
instance Str Text where
toString = T.unpack
toByteString = encodeUtf8
toText = id
toOctets = US.encode . toString
fromByteString = decodeUtf8
fromText = id
fromOctets = fromString . US.decode
smap = T.map
joinBy = T.intercalate
singleton = T.singleton
cons = T.cons
snoc = T.snoc
reverse = T.reverse
dropWhile = T.dropWhile
splitOn = T.splitOn
isPrefixOf = T.isPrefixOf
isSuffixOf = T.isSuffixOf
length = T.length
show :: (Show a, Str s) => a -> s
show = fromString . P.show
error :: Str s => s -> a
error = wrapString P.error
putStrLn :: Str s => s -> IO ()
putStrLn = wrapString P.putStrLn
wrapString :: Str s => (String -> a) -> s -> a
wrapString f = f . toString
wrapByteString :: Str s => (ByteString -> a) -> s -> a
wrapByteString f = f . toByteString
wrapByteString2 :: Str s => (ByteString -> ByteString -> a) -> s -> s -> a
wrapByteString2 f s1 s2 = f (toByteString s1) (toByteString s2)
wrapText :: Str s => (Text -> a) -> s -> a
wrapText f = f . toText
asString :: Str s => (String -> String) -> s -> s
asString func = fromString . func . toString
asByteString :: Str s => (ByteString -> ByteString) -> s -> s
asByteString func = fromByteString . func . toByteString
asText :: Str s => (Text -> Text) -> s -> s
asText func = fromText . func . toText
asOctets :: Str s => ([Octet] -> [Octet]) -> s -> s
asOctets f = fromOctets . f . toOctets
asString2 :: Str s => (String -> String -> String) -> s -> s -> s
asString2 f s1 s2 = fromString $ f (toString s1) (toString s2)
asByteString2 :: Str s => (ByteString -> ByteString -> ByteString) -> s -> s -> s
asByteString2 f s1 s2 = fromByteString $ f (toByteString s1) (toByteString s2)
asOctets2 :: Str s => ([Octet] -> [Octet] -> [Octet]) -> s -> s -> s
asOctets2 f s1 s2 = fromOctets $ f (toOctets s1) (toOctets s2)
unlines :: Str s => [s] -> s
unlines s = joinLines s `snoc` '\n'
joinLines :: Str s => [s] -> s
joinLines = joinBy "\n"
joinCommas :: Str s => [s] -> s
joinCommas = joinBy ","
joinSemis :: Str s => [s] -> s
joinSemis = joinBy ";"
joinSlashes :: Str s => [s] -> s
joinSlashes = joinBy "/"