content: {-# LANGUAGE PatternGuards, DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
  
  -- | ByteString wrappers which don't require special imports and are all UTF8 safe
  module General.Str(
      Str, strPack, strUnpack, strNull, strCopy, strCons,
      BStr, bstrPack, bstrUnpack, bstrReadFile, bstrSplitInfix, bstrNull, bstrStripPrefix, bstrTrimStart,
      LBStr, lbstrPack, lbstrUnpack, lbstrToChunks, lbstrFromChunks,
      BStr0, bstr0Join, bstr0Split
      ) where
  
  import qualified Foundation as Fdn
  import qualified Foundation.Collection as Fdn
  import qualified Data.ByteString.Char8 as BS
  import qualified Data.ByteString.UTF8 as US
  import qualified Data.ByteString.Lazy.Char8 as LBS
  import qualified Data.ByteString.Lazy.UTF8 as LUS
  import Control.DeepSeq
  import Data.Char
  import Data.Data
  import Data.List
  import Data.Semigroup
  import Data.String
  import Prelude
  
  
  newtype Str = Str {fromStr :: Fdn.String}
      deriving (Data,Typeable,Eq,Ord,Semigroup,Monoid)
  
  instance Show Str where show = strUnpack
  instance NFData Str where rnf x = x `seq` ()
  
  
  type BStr = BS.ByteString
  
  type LBStr = LBS.ByteString
  
  
  strPack :: String -> Str
  strPack = Str . fromString
  
  strUnpack :: Str -> String
  strUnpack = Fdn.toList . fromStr
  
  strCons :: Char -> Str -> Str
  strCons c = Str . Fdn.cons c . fromStr
  
  strCopy :: Str -> Str
  strCopy = Str . Fdn.copy . fromStr
  
  strNull :: Str -> Bool
  strNull = Fdn.null . fromStr
  
  bstrPack :: String -> BStr
  bstrPack = US.fromString
  
  bstrUnpack :: BStr -> String
  bstrUnpack = US.toString
  
  bstrReadFile :: FilePath -> IO BStr
  bstrReadFile = BS.readFile
  
  bstrSplitInfix :: BStr -> BStr -> Maybe (BStr, BStr)
  bstrSplitInfix needle haystack
      | (a,b) <- BS.breakSubstring needle haystack
      , not $ BS.null b
      = Just (a, BS.drop (BS.length needle) b)
  bstrSplitInfix _ _ = Nothing
  
  bstrNull :: BStr -> Bool
  bstrNull = BS.null
  
  bstrStripPrefix :: BStr -> BStr -> Maybe BStr
  bstrStripPrefix needle x
      | BS.isPrefixOf needle x = Just $ BS.drop (BS.length needle) x
      | otherwise = Nothing
  
  bstrTrimStart :: BStr -> BStr
  bstrTrimStart = BS.dropWhile isSpace
  
  lbstrToChunks :: LBStr -> [BStr]
  lbstrToChunks = LBS.toChunks
  
  lbstrFromChunks :: [BStr] -> LBStr
  lbstrFromChunks = LBS.fromChunks
  
  lbstrUnpack :: LBStr -> String
  lbstrUnpack = LUS.toString
  
  lbstrPack :: String -> LBStr
  lbstrPack = LUS.fromString
  
  
  type BStr0 = BStr
  
  bstr0Join :: [String] -> BStr0
  bstr0Join = LBS.toStrict . LUS.fromString . intercalate "\0"
  
  bstr0Split :: BStr0 -> [BStr]
  bstr0Split = BS.split '\0'
  