module Data.Rope.Body
( Body
, Count(..)
, Chunk(..)
, measureBody
, cons'
, snoc'
) where
import Prelude hiding (null, length)
import Data.FingerTree (FingerTree,(<|),(|>),Measured,measure,empty, singleton)
import Data.Data
import Data.Typeable
import Data.Monoid
import Data.Rope.Util.Reducer
import Data.ByteString (ByteString, null, length)
newtype Count = Count { getCount :: Int } deriving (Eq,Ord,Num,Show,Read,Enum,Data,Typeable)
instance Monoid Count where
mempty = 0
mappend = (+)
newtype Chunk = Chunk { unchunk :: ByteString } deriving (Eq,Ord,Show,Read,Data,Typeable)
instance Measured Count Chunk where
measure = Count . length . unchunk
type Body = FingerTree Count Chunk
measureBody :: Measured Count a => FingerTree Count a -> Int
measureBody = getCount . measure
cons' :: ByteString -> Body -> Body
b `cons'` t | null b = t
| otherwise = Chunk b <| t
snoc' :: Body -> ByteString -> Body
t `snoc'` b | null b = t
| otherwise = t |> Chunk b
instance Reducer ByteString Body where
unit b | null b = empty
| otherwise = singleton (Chunk b)
cons = cons'
snoc = snoc'