module Bio.SeqLoc.Position (
Offset(..)
, Pos(..)
, slide
, atPos
)
where
import Control.Applicative
import Control.Monad (liftM)
import qualified Data.ByteString as BSW
import qualified Data.ByteString.Char8 as BS
import Data.Int (Int64)
import qualified Data.Attoparsec.Char8 as AP (isDigit_w8)
import qualified Data.Attoparsec.Zepto as ZP
import Bio.SeqLoc.LocRepr
import Bio.SeqLoc.SeqLike
import Bio.SeqLoc.Strand
newtype Offset = Offset { unOffset :: Int64 } deriving (Eq, Ord, Show, Read, Num, Real, Enum, Integral)
instance LocRepr Offset where
repr = BS.pack . show . unOffset
unrepr = (negate <$> (ZP.string "-" *> decimal)) <|> (ZP.string "+" *> decimal) <|> decimal
where decimal = Offset . BSW.foldl' step 0 <$> ZP.takeWhile AP.isDigit_w8
step a w = a * 10 + fromIntegral (w 48)
data Pos = Pos { offset :: !Offset
, strand :: !Strand
}
deriving (Eq, Ord, Show, Read)
instance Stranded Pos where
revCompl (Pos off str) = Pos off (revCompl str)
instance LocRepr Pos where
repr (Pos off str) = BS.concat [ repr off, repr str ]
unrepr = Pos <$> unrepr <*> unrepr
slide :: Pos -> Offset -> Pos
slide (Pos off str) doff = Pos (off + doff) str
atPos :: (SeqLike s) => s -> Pos -> Maybe Char
atPos sequ (Pos off str) = liftM (stranded str) . ntAt sequ $ off