module Data.Woot.WString
( WString
, emptyWString
, fromList
, toList
, lengthWS
, (!?)
, indexOf
, insert
, subsection
, contains
, isEmpty
, nthVisible
, hideChar
) where
import Data.Maybe (fromMaybe, isJust)
import qualified Data.Vector as V
import Data.Woot.WChar
newtype WString = WString { wStringChars :: V.Vector WChar } deriving (Eq)
instance Show WString where
show = fmap wCharAlpha . toList . visibleChars
emptyWString :: WString
emptyWString = fromList [wCharBeginning, wCharEnding]
fromList :: [WChar] -> WString
fromList = WString . V.fromList
toList :: WString -> [WChar]
toList = V.toList . wStringChars
lengthWS :: WString -> Int
lengthWS = V.length . wStringChars
(!) :: WString -> Int -> WChar
(!) ws n = wStringChars ws V.! n
(!?) :: WString -> Int -> Maybe WChar
(!?) ws n = wStringChars ws V.!? n
indexOf :: WCharId -> WString -> Maybe Int
indexOf wcid = V.findIndex ((==) wcid . wCharId) . wStringChars
insert :: WChar -> Int -> WString -> WString
insert wc i (WString wcs) = WString $ V.concat [V.take i wcs, V.singleton wc, V.drop i wcs]
subsection :: WCharId -> WCharId -> WString -> WString
subsection prev next ws = WString . fromMaybe V.empty $ do
i <- indexOf prev ws
j <- indexOf next ws
return $ slice' i (j i) (wStringChars ws)
where
slice' i n = V.take n . V.drop i
contains :: WCharId -> WString -> Bool
contains wcid ws = isJust $ indexOf wcid ws
visibleChars :: WString -> WString
visibleChars = WString . V.filter wCharVisible . wStringChars
nthVisible :: Int -> WString -> Maybe WChar
nthVisible n = (!? n) . visibleChars
isEmpty :: WString -> Bool
isEmpty = V.null . wStringChars
hideChar :: WCharId -> WString -> WString
hideChar wid ws@(WString wcs) = WString $
maybe wcs (\i -> wcs V.// [(i, hide $ ws ! i)]) mindex
where
mindex = indexOf wid ws