module SequenceFormats.Bed (BedEntry(..), readBedFile) where

import SequenceFormats.Utils (Chrom(..), readFileProd, consumeProducer)

import Data.Char (isSpace)
import qualified Data.Attoparsec.ByteString.Char8 as A
import Pipes (Producer)
import Pipes.Safe (MonadSafe)

data BedEntry = BedEntry Chrom Int Int deriving (Int -> BedEntry -> ShowS
[BedEntry] -> ShowS
BedEntry -> String
(Int -> BedEntry -> ShowS)
-> (BedEntry -> String) -> ([BedEntry] -> ShowS) -> Show BedEntry
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BedEntry] -> ShowS
$cshowList :: [BedEntry] -> ShowS
show :: BedEntry -> String
$cshow :: BedEntry -> String
showsPrec :: Int -> BedEntry -> ShowS
$cshowsPrec :: Int -> BedEntry -> ShowS
Show, BedEntry -> BedEntry -> Bool
(BedEntry -> BedEntry -> Bool)
-> (BedEntry -> BedEntry -> Bool) -> Eq BedEntry
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BedEntry -> BedEntry -> Bool
$c/= :: BedEntry -> BedEntry -> Bool
== :: BedEntry -> BedEntry -> Bool
$c== :: BedEntry -> BedEntry -> Bool
Eq)

bedFileParser :: A.Parser BedEntry
bedFileParser :: Parser BedEntry
bedFileParser = Chrom -> Int -> Int -> BedEntry
BedEntry (Chrom -> Int -> Int -> BedEntry)
-> Parser ByteString Chrom
-> Parser ByteString (Int -> Int -> BedEntry)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString Chrom
chrom Parser ByteString (Int -> Int -> BedEntry)
-> Parser ByteString ()
-> Parser ByteString (Int -> Int -> BedEntry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString ()
A.skipSpace Parser ByteString (Int -> Int -> BedEntry)
-> Parser ByteString Int -> Parser ByteString (Int -> BedEntry)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString Int
forall a. Integral a => Parser a
A.decimal Parser ByteString (Int -> BedEntry)
-> Parser ByteString () -> Parser ByteString (Int -> BedEntry)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString ()
A.skipSpace Parser ByteString (Int -> BedEntry)
-> Parser ByteString Int -> Parser BedEntry
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser ByteString Int
forall a. Integral a => Parser a
A.decimal Parser BedEntry -> Parser ByteString () -> Parser BedEntry
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser ByteString ()
A.endOfLine
  where
    chrom :: Parser ByteString Chrom
chrom = ByteString -> Chrom
Chrom (ByteString -> Chrom)
-> Parser ByteString ByteString -> Parser ByteString Chrom
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Bool) -> Parser ByteString ByteString
A.takeTill Char -> Bool
isSpace

readBedFile :: (MonadSafe m) => FilePath -> Producer BedEntry m ()
readBedFile :: String -> Producer BedEntry m ()
readBedFile String
bedFile = Parser BedEntry
-> Producer ByteString m () -> Producer BedEntry m ()
forall (m :: * -> *) a.
MonadThrow m =>
Parser a -> Producer ByteString m () -> Producer a m ()
consumeProducer Parser BedEntry
bedFileParser (String -> Producer ByteString m ()
forall (m :: * -> *).
MonadSafe m =>
String -> Producer ByteString m ()
readFileProd String
bedFile)