{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable, MultiParamTypeClasses, FlexibleContexts, TypeSynonymInstances #-} 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'