module Data.AttoBencode.Encode (encode) where
import Data.AttoBencode.Types
import Blaze.ByteString.Builder
import Blaze.Text.Int (integral)
import Data.Map (toAscList)
import Data.Monoid
import qualified Data.ByteString.Char8 as B
import Data.Word (Word8)
encode :: ToBencode a => a -> B.ByteString
encode = toByteString . fromBValue . toBencode
dWord, iWord, eWord, lWord, colon :: Word8
dWord = 100
eWord = 101
lWord = 108
iWord = 105
colon = 58
fromBValue :: BValue -> Builder
fromBValue (BString s) = fromString s
fromBValue (BList l) = fromWord8 lWord <> (mconcat . map fromBValue) l <> fromWord8 eWord
fromBValue (BDict d) = fromWord8 dWord <> (mconcat . map fromPair) (toAscList d) <> fromWord8 eWord
fromBValue (BInt n) = fromWord8 iWord <> integral n <> fromWord8 eWord
fromString :: B.ByteString -> Builder
fromString s = integral (B.length s) <> fromWord8 colon <> fromByteString s
fromPair :: (B.ByteString, BValue) -> Builder
fromPair (k, v) = fromString k <> fromBValue v