module HaskellWorks.Data.Conduit.Tokenize.Attoparsec.LineColumn
( Position (..)
) where
import Control.Exception (Exception)
import Control.Monad.Trans.Resource (MonadThrow)
import qualified Data.Attoparsec.Types as A
import qualified Data.ByteString as B
import Data.Conduit
import qualified Data.Text as T
import HaskellWorks.Data.Conduit.Tokenize.Attoparsec.Internal
import Prelude hiding (lines)
data Position = Position
{ posLine :: !Int
, posCol :: !Int
}
deriving (Eq, Ord)
instance Show Position where
show (Position l c) = show l ++ ':' : show c
instance Exception (ParseError Position)
instance Show (ParseDelta Position) where
show (ParseDelta s e) = show s ++ '-' : show e
instance AttoparsecState B.ByteString Position where
getState = B.foldl' f (Position 0 0)
where
f (Position l c) ch | ch == 10 = Position (l + 1) 0
| otherwise = Position l (c + 1)
modState x (Position lines cols) =
lines' `seq` cols' `seq` Position lines' cols'
where
Position dlines dcols = getState x
lines' = lines + dlines
cols' = (if dlines > 0 then 1 else cols) + dcols
instance AttoparsecState T.Text Position where
getState = T.foldl' f (Position 0 0)
where
f (Position l c) ch | ch == '\n' = Position (l + 1) 0
| otherwise = Position l (c + 1)
modState x (Position lines cols) =
lines' `seq` cols' `seq` Position lines' cols'
where
Position dlines dcols = getState x
lines' = lines + dlines
cols' = (if dlines > 0 then 1 else cols) + dcols