Commits

FlorianHartwig  committed f83a574

Make encoding more convenient, bump version for changed encoding API

  • Participants
  • Parent commits e3036a1

Comments (0)

Files changed (4)

File AttoBencode.cabal

 Name:                AttoBencode
-Version:             0.1
+Version:             0.2
 Synopsis:            Fast Bencode encoding and parsing library
 Homepage:            http://bitbucket.org/FlorianHartwig/attobencode
 License:             BSD3

File src/Data/AttoBencode/Encode.hs

 import qualified Data.ByteString.Char8 as B
 import Data.Word (Word8)
 
--- | Serialise a Benocde value to a (strict) ByteString
-encode :: BValue -> B.ByteString
-encode = toByteString . fromBValue
+-- | Serialise a Bencode value to a (strict) ByteString
+encode :: ToBencode a => a -> B.ByteString
+encode = toByteString . fromBValue . toBencode
 
 dWord, iWord, eWord, lWord, colon :: Word8
 dWord = 100

File src/Data/AttoBencode/Types.hs

+{-# LANGUAGE FlexibleInstances #-}
+
 module Data.AttoBencode.Types where
 
-import Data.Map (Map)
-import qualified Data.ByteString as B
+import qualified Data.Map as M
+import Data.ByteString (ByteString)
 
 -- | The Haskell data type for Bencode values
-data BValue = BString !B.ByteString
+data BValue = BString !ByteString
             | BInt !Integer
             | BList ![BValue]
             | BDict !Dict
     deriving (Show, Eq)
 
 -- | A Bencode dictionary is a map from ByteStrings to Bencode values
-type Dict = Map B.ByteString BValue
+type Dict = M.Map ByteString BValue
+
+-- | A type that can be converted to a BValue
+class ToBencode a where
+    toBencode :: a -> BValue
+
+instance ToBencode ByteString where
+    toBencode = BString
+
+instance ToBencode Integer where
+    toBencode = BInt
+
+instance ToBencode Int where
+    toBencode = BInt . fromIntegral
+
+instance (ToBencode a) => ToBencode [a] where
+    toBencode = BList . map toBencode
+
+instance (ToBencode a) => ToBencode (M.Map ByteString a) where
+    toBencode = BDict . M.map toBencode
+
+instance (ToBencode a) => ToBencode [(ByteString, a)] where
+    toBencode = BDict . M.fromList . map (\(k, v) -> (k, toBencode v))
+
+instance ToBencode BValue where
+    toBencode = id
+-- TODO: make sure these are inlined
     arbitrary   = fmap B.pack arbitrary
 
 prop_EncodeInteger :: Integer -> Bool
-prop_EncodeInteger n = encode (BInt n) == B.pack ("i" ++ show n ++ "e")
+prop_EncodeInteger n = encode n == B.pack ("i" ++ show n ++ "e")
 
 prop_EncodeString :: B.ByteString -> Bool
 prop_EncodeString bs =
-    encode (BString bs) == B.pack (show (B.length bs) ++ ":") `B.append` bs
+    encode bs == B.pack (show (B.length bs) ++ ":") `B.append` bs
 
 prop_EncodeDecode bv = case decode (encode bv) of
                             Just bv' -> bv == bv'