shell-escape-0.1.1: Text/ShellEscape/EscapeVector.hs
module Text.ShellEscape.EscapeVector where
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as ByteString
import Data.Vector (Vector)
import qualified Data.Vector as Vector
import qualified Data.Vector.Mutable as Vector (new, write)
import qualified Text.ShellEscape.Put as Put
type EscapeVector escapingMode = Vector (Char, escapingMode)
escWith :: (Char -> escapingMode) -> ByteString -> EscapeVector escapingMode
escWith cf b = Vector.create $ do
v <- Vector.new (ByteString.length b)
sequence_ . snd $ ByteString.foldl' (f v) (0, []) b
return v
where
f v (i, ops) c = (i + 1, Vector.write v i (c, cf c) : ops)
stripEsc :: Vector (Char, escapingMode) -> ByteString
stripEsc v = ByteString.unfoldr f . fst $ Vector.unzip v
where
f v | Vector.null v = Nothing
| otherwise = Just (Vector.unsafeHead v, Vector.unsafeTail v)
interpretEsc v f finish init = (eval . (finish lastMode :)) instructions
where
eval = Put.runPut' . sequence_ . reverse
(instructions, lastMode) = Vector.foldl' f' init v
where
f' (list, mode) (c, e) = (put:list, mode')
where
(put, mode') = f mode (c, e)