module Data.AttoBencode.Parser
( decode
, bValue
) where
import Data.AttoBencode.Types
import Prelude hiding (take)
import Data.Attoparsec (maybeResult, parse, Parser)
import Data.Attoparsec.Char8 (char, decimal, signed, take)
import Control.Applicative (many, (<$>), (<|>), (*>), (<*))
import Data.Map (fromList)
import qualified Data.ByteString as B
decode :: (FromBencode a) => B.ByteString -> Maybe a
decode bs = maybeResult (parse bValue bs) >>= fromBencode
bValue :: Parser BValue
bValue = stringParser <|> intParser <|> listParser <|> dictParser
bsParser :: Parser B.ByteString
bsParser =
do l <- decimal
_ <- char ':'
take l
stringParser :: Parser BValue
stringParser = BString <$> bsParser
intParser :: Parser BValue
intParser = BInt <$> (char 'i' *> signed decimal <* char 'e')
listParser :: Parser BValue
listParser = BList <$> (char 'l' *> many bValue <* char 'e')
pairParser :: Parser (B.ByteString, BValue)
pairParser =
do !key <- bsParser
!value <- bValue
return (key, value)
dictParser :: Parser BValue
dictParser =
do _ <- char 'd'
!pairs <- many pairParser
_ <- char 'e'
return $ BDict $ fromList pairs