{- | see "Data.ByteString.Search" package

    break, split ops on 'ByteString'

    regex is treated as ordinary String
    
    break & split are now '/', '-/', '/-' 
    
    replace moved to "Text.Regex.Do.Replace.Fast"
    -}
module Text.Regex.Do.Split
    (Split(..),
    SplitFront(..),
    SplitEnd(..),
    T,L
    ) where

import qualified Data.ByteString.Search as S
import Data.ByteString as B hiding (break, breakEnd, split)
import Prelude hiding (break,(/))
import Text.Regex.Do.Match.Matchf


-- | Break result: tuple
type T = (B.ByteString,B.ByteString)

-- | Split result: list
type L = [B.ByteString] 



{- | slices 'ByteString'. drops needle
    
    to avoid clash with 'Prelude':
    
    @import Prelude hiding((/))@       

    or qualify '/' with alias e.g. (assuming this module is imported with S alias):
       
    @S./@           
    
    body -> pattern -> result
    -}
class Split out where
    (/)::ByteString -> ByteString -> out


instance Split (ByteString,ByteString) where
    / :: ByteString -> ByteString -> (ByteString, ByteString)
(/) body0 :: ByteString
body0 pat0 :: ByteString
pat0 =  (ByteString
h1,ByteString
t2)
      where (h1 :: ByteString
h1,t1 :: ByteString
t1) = ByteString -> ByteString -> (ByteString, ByteString)
S.breakOn ByteString
pat1 ByteString
body0
            len1 :: Int
len1 = ByteString -> Int
B.length ByteString
pat1
            t2 :: ByteString
t2 = Int -> ByteString -> ByteString
B.drop Int
len1 ByteString
t1
            !pat1 :: ByteString
pat1 = ByteString -> ByteString
checkPattern ByteString
pat0
{- ^  >>> "a\nbc\nde" / "\n"

        ("a", "bc\\nde")    -}


-- | keep needle \@ front
class SplitFront out where
    (-/)::ByteString        
            -> ByteString   
            -> out


instance SplitFront (ByteString,ByteString) where
    -/ :: ByteString -> ByteString -> (ByteString, ByteString)
(-/) body0 :: ByteString
body0 pat0 :: ByteString
pat0 = ByteString -> ByteString -> (ByteString, ByteString)
S.breakOn ByteString
pat1 ByteString
body0
         where !pat1 :: ByteString
pat1 = ByteString -> ByteString
checkPattern ByteString
pat0
{- ^ >>> "a\nbc\nde" -/ "\n" 

        ("a", "\\nbc\\nde")     -}


-- | keep needle \@ end
class SplitEnd out where
    (/-)::ByteString       
            -> ByteString   
            -> out


instance SplitEnd (ByteString,ByteString) where
    /- :: ByteString -> ByteString -> (ByteString, ByteString)
(/-) body0 :: ByteString
body0 pat0 :: ByteString
pat0 = ByteString -> ByteString -> (ByteString, ByteString)
S.breakAfter ByteString
pat1 ByteString
body0
         where !pat1 :: ByteString
pat1 = ByteString -> ByteString
checkPattern ByteString
pat0
{- ^ >>> "a\nbc\nde" /- "\n"  

    ("a\\n", "bc\\nde")         -}


instance Split [ByteString] where
    / :: ByteString -> ByteString -> [ByteString]
(/) body0 :: ByteString
body0 pat0 :: ByteString
pat0 = ByteString -> ByteString -> [ByteString]
S.split ByteString
pat1 ByteString
body0
         where !pat1 :: ByteString
pat1 = ByteString -> ByteString
checkPattern ByteString
pat0
{- ^ >>> "a bc de" / " "      -- space may be used

    \["a", "bc", "de"]      -}


instance SplitFront [ByteString] where
    -/ :: ByteString -> ByteString -> [ByteString]
(-/) body0 :: ByteString
body0 pat0 :: ByteString
pat0 = ByteString -> ByteString -> [ByteString]
S.splitKeepFront ByteString
pat1 ByteString
body0
         where !pat1 :: ByteString
pat1 = ByteString -> ByteString
checkPattern ByteString
pat0
{- ^ >>> "a\nbc\nde" -/ "\n"

    \["a", "\\nbc", "\\nde"]        -}


instance SplitEnd [ByteString] where
    /- :: ByteString -> ByteString -> [ByteString]
(/-) body0 :: ByteString
body0 pat0 :: ByteString
pat0 = ByteString -> ByteString -> [ByteString]
S.splitKeepEnd ByteString
pat1 ByteString
body0
         where !pat1 :: ByteString
pat1 = ByteString -> ByteString
checkPattern ByteString
pat0
{- ^ >>> "a\nbc\nde" /- "\n"

    \["a\\n", "bc\\n", "de"]     -}