stringsearch-0.3.0: Data/ByteString/Search/Substitution.hs
-- |
-- Module : Data.ByteString.Search.Substitution
-- Copyright : Daniel Fischer
-- Licence : BSD3
-- Maintainer : Daniel Fischer <daniel.is.fischer@web.de>
-- Stability : Provisional
-- Portability : portable
--
-- Class for values to be substituted into strict and lazy 'S.ByteString's
-- by the @replace@ functions defined in this package.
--
module Data.ByteString.Search.Substitution ( Substitution(..)) where
import qualified Data.ByteString as S
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Lazy.Internal as LI
-- | Type class of meaningful substitutions for replace functions
-- on ByteStrings. Instances for strict and lazy ByteStrings are
-- provided here.
class Substitution a where
-- | @substitution@ transforms a value to a substitution function.
substitution :: a -> ([S.ByteString] -> [S.ByteString])
{-# INLINE substitution #-}
-- | @prependCycle sub lazyBS@ shall prepend infinitely many copies
-- of @sub@ to @lazyBS@ without entering an infinite loop in case
-- of an empty @sub@, so e.g.
--
-- @
-- 'prependCycle' \"\" \"ab\" == \"ab\"
-- @
--
-- shall (quickly) evaluate to 'True'.
-- For non-empty @sub@, the cycle shall be constructed efficiently.
prependCycle :: a -> (L.ByteString -> L.ByteString)
{-# INLINE prependCycle #-}
instance Substitution S.ByteString where
substitution sub = if S.null sub then id else (sub :)
prependCycle sub
| S.null sub = id
| otherwise = let c = LI.Chunk sub c in const c
instance Substitution L.ByteString where
substitution LI.Empty = id
substitution (LI.Chunk c t) = (c :) . flip (LI.foldrChunks (:)) t
prependCycle sub
| L.null sub = id
prependCycle sub = let cyc = LI.foldrChunks LI.Chunk cyc sub in const cyc