diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2013-09-28 05:39:46 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2013-09-28 05:39:46 +0400 |
commit | 51fecc396f8c7ccd3f91125d5fbac040051915c6 (patch) | |
tree | a1f4b0f63408d88cd307828c150eac1aae8d44b3 | |
parent | 484e45c985a4a63a21ed9ef553373d58cbed703e (diff) |
Rename BEncode to BValue
-rw-r--r-- | src/Data/BEncode.hs | 81 | ||||
-rw-r--r-- | tests/properties.hs | 4 |
2 files changed, 43 insertions, 42 deletions
diff --git a/src/Data/BEncode.hs b/src/Data/BEncode.hs index e932254..4133ae5 100644 --- a/src/Data/BEncode.hs +++ b/src/Data/BEncode.hs | |||
@@ -62,7 +62,7 @@ module Data.BEncode | |||
62 | , BDict | 62 | , BDict |
63 | , BKey | 63 | , BKey |
64 | 64 | ||
65 | , BEncode(..) | 65 | , BValue (..) |
66 | , ppBEncode | 66 | , ppBEncode |
67 | 67 | ||
68 | -- * Conversion | 68 | -- * Conversion |
@@ -138,8 +138,8 @@ import GHC.Generics | |||
138 | 138 | ||
139 | type BInteger = Integer | 139 | type BInteger = Integer |
140 | type BString = ByteString | 140 | type BString = ByteString |
141 | type BList = [BEncode] | 141 | type BList = [BValue] |
142 | type BDict = Map BKey BEncode | 142 | type BDict = Map BKey BValue |
143 | type BKey = ByteString | 143 | type BKey = ByteString |
144 | 144 | ||
145 | -- | 'BEncode' is straightforward ADT for b-encoded values. Please | 145 | -- | 'BEncode' is straightforward ADT for b-encoded values. Please |
@@ -147,13 +147,14 @@ type BKey = ByteString | |||
147 | -- compare BEncoded values without serialization and vice versa. | 147 | -- compare BEncoded values without serialization and vice versa. |
148 | -- Lists is not required to be sorted through. | 148 | -- Lists is not required to be sorted through. |
149 | -- | 149 | -- |
150 | data BEncode = BInteger !BInteger -- ^ bencode integers; | 150 | data BValue |
151 | | BString !BString -- ^ bencode strings; | 151 | = BInteger !BInteger -- ^ bencode integers; |
152 | | BList BList -- ^ list of bencode values; | 152 | | BString !BString -- ^ bencode strings; |
153 | | BDict BDict -- ^ bencode key-value dictionary. | 153 | | BList BList -- ^ list of bencode values; |
154 | deriving (Show, Read, Eq, Ord) | 154 | | BDict BDict -- ^ bencode key-value dictionary. |
155 | 155 | deriving (Show, Read, Eq, Ord) | |
156 | instance NFData BEncode where | 156 | |
157 | instance NFData BValue where | ||
157 | rnf (BInteger i) = rnf i | 158 | rnf (BInteger i) = rnf i |
158 | rnf (BString s) = rnf s | 159 | rnf (BString s) = rnf s |
159 | rnf (BList l) = rnf l | 160 | rnf (BList l) = rnf l |
@@ -188,25 +189,25 @@ type Result = Either String | |||
188 | -- | 189 | -- |
189 | class BEncodable a where | 190 | class BEncodable a where |
190 | -- | See an example of implementation here 'Assoc' | 191 | -- | See an example of implementation here 'Assoc' |
191 | toBEncode :: a -> BEncode | 192 | toBEncode :: a -> BValue |
192 | 193 | ||
193 | #if __GLASGOW_HASKELL__ >= 702 | 194 | #if __GLASGOW_HASKELL__ >= 702 |
194 | default toBEncode | 195 | default toBEncode |
195 | :: Generic a | 196 | :: Generic a |
196 | => GBEncodable (Rep a) BEncode | 197 | => GBEncodable (Rep a) BValue |
197 | => a -> BEncode | 198 | => a -> BValue |
198 | 199 | ||
199 | toBEncode = gto . from | 200 | toBEncode = gto . from |
200 | #endif | 201 | #endif |
201 | 202 | ||
202 | -- | See an example of implementation here 'reqKey'. | 203 | -- | See an example of implementation here 'reqKey'. |
203 | fromBEncode :: BEncode -> Result a | 204 | fromBEncode :: BValue -> Result a |
204 | 205 | ||
205 | #if __GLASGOW_HASKELL__ >= 702 | 206 | #if __GLASGOW_HASKELL__ >= 702 |
206 | default fromBEncode | 207 | default fromBEncode |
207 | :: Generic a | 208 | :: Generic a |
208 | => GBEncodable (Rep a) BEncode | 209 | => GBEncodable (Rep a) BValue |
209 | => BEncode -> Result a | 210 | => BValue -> Result a |
210 | 211 | ||
211 | fromBEncode x = to <$> gfrom x | 212 | fromBEncode x = to <$> gfrom x |
212 | #endif | 213 | #endif |
@@ -237,7 +238,7 @@ class GBEncodable f e where | |||
237 | gfrom :: e -> Result (f a) | 238 | gfrom :: e -> Result (f a) |
238 | 239 | ||
239 | instance BEncodable f | 240 | instance BEncodable f |
240 | => GBEncodable (K1 R f) BEncode where | 241 | => GBEncodable (K1 R f) BValue where |
241 | {-# INLINE gto #-} | 242 | {-# INLINE gto #-} |
242 | gto = toBEncode . unK1 | 243 | gto = toBEncode . unK1 |
243 | 244 | ||
@@ -291,7 +292,7 @@ selRename :: String -> String | |||
291 | selRename = dropWhile ('_'==) | 292 | selRename = dropWhile ('_'==) |
292 | 293 | ||
293 | gfromM1S :: forall c. Selector c | 294 | gfromM1S :: forall c. Selector c |
294 | => GBEncodable f BEncode | 295 | => GBEncodable f BValue |
295 | => BDict -> Result (M1 i c f p) | 296 | => BDict -> Result (M1 i c f p) |
296 | gfromM1S dict | 297 | gfromM1S dict |
297 | | Just va <- M.lookup (BC.pack (selRename name)) dict = M1 <$> gfrom va | 298 | | Just va <- M.lookup (BC.pack (selRename name)) dict = M1 <$> gfrom va |
@@ -299,7 +300,7 @@ gfromM1S dict | |||
299 | where | 300 | where |
300 | name = selName (error "gfromM1S: impossible" :: M1 i c f p) | 301 | name = selName (error "gfromM1S: impossible" :: M1 i c f p) |
301 | 302 | ||
302 | instance (Selector s, GBEncodable f BEncode) | 303 | instance (Selector s, GBEncodable f BValue) |
303 | => GBEncodable (M1 S s f) BDict where | 304 | => GBEncodable (M1 S s f) BDict where |
304 | {-# INLINE gto #-} | 305 | {-# INLINE gto #-} |
305 | gto s @ (M1 x) = BC.pack (selRename (selName s)) `M.singleton` gto x | 306 | gto s @ (M1 x) = BC.pack (selRename (selName s)) `M.singleton` gto x |
@@ -308,7 +309,7 @@ instance (Selector s, GBEncodable f BEncode) | |||
308 | gfrom = gfromM1S | 309 | gfrom = gfromM1S |
309 | 310 | ||
310 | -- TODO DList | 311 | -- TODO DList |
311 | instance GBEncodable f BEncode | 312 | instance GBEncodable f BValue |
312 | => GBEncodable (M1 S s f) BList where | 313 | => GBEncodable (M1 S s f) BList where |
313 | {-# INLINE gto #-} | 314 | {-# INLINE gto #-} |
314 | gto (M1 x) = [gto x] | 315 | gto (M1 x) = [gto x] |
@@ -318,7 +319,7 @@ instance GBEncodable f BEncode | |||
318 | {-# INLINE gfrom #-} | 319 | {-# INLINE gfrom #-} |
319 | 320 | ||
320 | instance (Constructor c, GBEncodable f BDict, GBEncodable f BList) | 321 | instance (Constructor c, GBEncodable f BDict, GBEncodable f BList) |
321 | => GBEncodable (M1 C c f) BEncode where | 322 | => GBEncodable (M1 C c f) BValue where |
322 | {-# INLINE gto #-} | 323 | {-# INLINE gto #-} |
323 | gto con @ (M1 x) | 324 | gto con @ (M1 x) |
324 | | conIsRecord con = BDict (gto x) | 325 | | conIsRecord con = BDict (gto x) |
@@ -343,7 +344,7 @@ instance GBEncodable f e | |||
343 | -- Native instances | 344 | -- Native instances |
344 | --------------------------------------------------------------------} | 345 | --------------------------------------------------------------------} |
345 | 346 | ||
346 | instance BEncodable BEncode where | 347 | instance BEncodable BValue where |
347 | toBEncode = id | 348 | toBEncode = id |
348 | {-# INLINE toBEncode #-} | 349 | {-# INLINE toBEncode #-} |
349 | 350 | ||
@@ -393,11 +394,11 @@ instance BEncodable BDict where | |||
393 | requires -XUndecidableInstances, so we avoid it | 394 | requires -XUndecidableInstances, so we avoid it |
394 | -} | 395 | -} |
395 | 396 | ||
396 | toBEncodeIntegral :: Integral a => a -> BEncode | 397 | toBEncodeIntegral :: Integral a => a -> BValue |
397 | toBEncodeIntegral = BInteger . fromIntegral | 398 | toBEncodeIntegral = BInteger . fromIntegral |
398 | {-# INLINE toBEncodeIntegral #-} | 399 | {-# INLINE toBEncodeIntegral #-} |
399 | 400 | ||
400 | fromBEncodeIntegral :: forall a. Typeable a => Integral a => BEncode -> Result a | 401 | fromBEncodeIntegral :: forall a. Typeable a => Integral a => BValue -> Result a |
401 | fromBEncodeIntegral (BInteger i) = pure (fromIntegral i) | 402 | fromBEncodeIntegral (BInteger i) = pure (fromIntegral i) |
402 | fromBEncodeIntegral _ | 403 | fromBEncodeIntegral _ |
403 | = decodingError $ show $ typeOf (undefined :: a) | 404 | = decodingError $ show $ typeOf (undefined :: a) |
@@ -516,7 +517,7 @@ instance BEncodable a => BEncodable (Map ByteString a) where | |||
516 | {-# INLINE fromBEncode #-} | 517 | {-# INLINE fromBEncode #-} |
517 | 518 | ||
518 | instance (Eq a, BEncodable a) => BEncodable (Set a) where | 519 | instance (Eq a, BEncodable a) => BEncodable (Set a) where |
519 | {-# SPECIALIZE instance BEncodable (Set BEncode) #-} | 520 | {-# SPECIALIZE instance BEncodable (Set BValue) #-} |
520 | toBEncode = BList . map toBEncode . S.toAscList | 521 | toBEncode = BList . map toBEncode . S.toAscList |
521 | {-# INLINE toBEncode #-} | 522 | {-# INLINE toBEncode #-} |
522 | 523 | ||
@@ -547,9 +548,9 @@ instance BEncodable () where | |||
547 | {-# INLINE fromBEncode #-} | 548 | {-# INLINE fromBEncode #-} |
548 | 549 | ||
549 | instance (BEncodable a, BEncodable b) => BEncodable (a, b) where | 550 | instance (BEncodable a, BEncodable b) => BEncodable (a, b) where |
550 | {-# SPECIALIZE instance (BEncodable b) => BEncodable (BEncode, b) #-} | 551 | {-# SPECIALIZE instance (BEncodable b) => BEncodable (BValue, b) #-} |
551 | {-# SPECIALIZE instance (BEncodable a) => BEncodable (a, BEncode) #-} | 552 | {-# SPECIALIZE instance (BEncodable a) => BEncodable (a, BValue) #-} |
552 | {-# SPECIALIZE instance BEncodable (BEncode, BEncode) #-} | 553 | {-# SPECIALIZE instance BEncodable (BValue, BValue) #-} |
553 | toBEncode (a, b) = BList [toBEncode a, toBEncode b] | 554 | toBEncode (a, b) = BList [toBEncode a, toBEncode b] |
554 | {-# INLINE toBEncode #-} | 555 | {-# INLINE toBEncode #-} |
555 | 556 | ||
@@ -622,7 +623,7 @@ instance (BEncodable a, BEncodable b, BEncodable c, BEncodable d, BEncodable e) | |||
622 | -- > ] | 623 | -- > ] |
623 | -- > ... | 624 | -- > ... |
624 | -- | 625 | -- |
625 | newtype Assoc = Assoc { unAssoc :: Maybe (ByteString, BEncode) } | 626 | newtype Assoc = Assoc { unAssoc :: Maybe (ByteString, BValue) } |
626 | 627 | ||
627 | -- | Make required key value pair. | 628 | -- | Make required key value pair. |
628 | (-->) :: BEncodable a => ByteString -> a -> Assoc | 629 | (-->) :: BEncodable a => ByteString -> a -> Assoc |
@@ -637,13 +638,13 @@ key -->? mval = Assoc $ ((,) key . toBEncode) <$> mval | |||
637 | {-# INLINE (-->?) #-} | 638 | {-# INLINE (-->?) #-} |
638 | 639 | ||
639 | -- | Build BEncode dictionary using key -> value description. | 640 | -- | Build BEncode dictionary using key -> value description. |
640 | fromAssocs :: [Assoc] -> BEncode | 641 | fromAssocs :: [Assoc] -> BValue |
641 | fromAssocs = BDict . M.fromList . mapMaybe unAssoc | 642 | fromAssocs = BDict . M.fromList . mapMaybe unAssoc |
642 | {-# INLINE fromAssocs #-} | 643 | {-# INLINE fromAssocs #-} |
643 | 644 | ||
644 | -- | A faster version of 'fromAssocs'. Should be used only when keys | 645 | -- | A faster version of 'fromAssocs'. Should be used only when keys |
645 | -- in builder list are sorted by ascending. | 646 | -- in builder list are sorted by ascending. |
646 | fromAscAssocs :: [Assoc] -> BEncode | 647 | fromAscAssocs :: [Assoc] -> BValue |
647 | fromAscAssocs = BDict . M.fromAscList . mapMaybe unAssoc | 648 | fromAscAssocs = BDict . M.fromAscList . mapMaybe unAssoc |
648 | {-# INLINE fromAscAssocs #-} | 649 | {-# INLINE fromAscAssocs #-} |
649 | 650 | ||
@@ -697,25 +698,25 @@ optKey d key | |||
697 | --------------------------------------------------------------------} | 698 | --------------------------------------------------------------------} |
698 | 699 | ||
699 | -- | Test if bencoded value is an integer. | 700 | -- | Test if bencoded value is an integer. |
700 | isInteger :: BEncode -> Bool | 701 | isInteger :: BValue -> Bool |
701 | isInteger (BInteger _) = True | 702 | isInteger (BInteger _) = True |
702 | isInteger _ = False | 703 | isInteger _ = False |
703 | {-# INLINE isInteger #-} | 704 | {-# INLINE isInteger #-} |
704 | 705 | ||
705 | -- | Test if bencoded value is a string, both raw and utf8 encoded. | 706 | -- | Test if bencoded value is a string, both raw and utf8 encoded. |
706 | isString :: BEncode -> Bool | 707 | isString :: BValue -> Bool |
707 | isString (BString _) = True | 708 | isString (BString _) = True |
708 | isString _ = False | 709 | isString _ = False |
709 | {-# INLINE isString #-} | 710 | {-# INLINE isString #-} |
710 | 711 | ||
711 | -- | Test if bencoded value is a list. | 712 | -- | Test if bencoded value is a list. |
712 | isList :: BEncode -> Bool | 713 | isList :: BValue -> Bool |
713 | isList (BList _) = True | 714 | isList (BList _) = True |
714 | isList _ = False | 715 | isList _ = False |
715 | {-# INLINE isList #-} | 716 | {-# INLINE isList #-} |
716 | 717 | ||
717 | -- | Test if bencoded value is a dictionary. | 718 | -- | Test if bencoded value is a dictionary. |
718 | isDict :: BEncode -> Bool | 719 | isDict :: BValue -> Bool |
719 | isDict (BList _) = True | 720 | isDict (BList _) = True |
720 | isDict _ = False | 721 | isDict _ = False |
721 | {-# INLINE isDict #-} | 722 | {-# INLINE isDict #-} |
@@ -726,12 +727,12 @@ isDict _ = False | |||
726 | 727 | ||
727 | -- | Convert bencoded value to raw bytestring according to the | 728 | -- | Convert bencoded value to raw bytestring according to the |
728 | -- specification. | 729 | -- specification. |
729 | encode :: BEncode -> Lazy.ByteString | 730 | encode :: BValue -> Lazy.ByteString |
730 | encode = B.toLazyByteString . builder | 731 | encode = B.toLazyByteString . builder |
731 | 732 | ||
732 | -- | Try to convert raw bytestring to bencoded value according to | 733 | -- | Try to convert raw bytestring to bencoded value according to |
733 | -- specification. | 734 | -- specification. |
734 | decode :: ByteString -> Result BEncode | 735 | decode :: ByteString -> Result BValue |
735 | decode = P.parseOnly parser | 736 | decode = P.parseOnly parser |
736 | 737 | ||
737 | -- | The same as 'decode' but returns any bencodable value. | 738 | -- | The same as 'decode' but returns any bencodable value. |
@@ -747,7 +748,7 @@ encoded = encode . toBEncode | |||
747 | --------------------------------------------------------------------} | 748 | --------------------------------------------------------------------} |
748 | 749 | ||
749 | -- | BEncode format encoder according to specification. | 750 | -- | BEncode format encoder according to specification. |
750 | builder :: BEncode -> B.Builder | 751 | builder :: BValue -> B.Builder |
751 | builder = go | 752 | builder = go |
752 | where | 753 | where |
753 | go (BInteger i) = B.word8 (c2w 'i') <> | 754 | go (BInteger i) = B.word8 (c2w 'i') <> |
@@ -770,7 +771,7 @@ builder = go | |||
770 | 771 | ||
771 | -- TODO try to replace peekChar with something else | 772 | -- TODO try to replace peekChar with something else |
772 | -- | BEncode format parser according to specification. | 773 | -- | BEncode format parser according to specification. |
773 | parser :: Parser BEncode | 774 | parser :: Parser BValue |
774 | parser = valueP | 775 | parser = valueP |
775 | where | 776 | where |
776 | valueP = do | 777 | valueP = do |
@@ -822,7 +823,7 @@ ppBS = text . map w2c . B.unpack | |||
822 | 823 | ||
823 | -- | Convert to easily readable JSON-like document. Typically used for | 824 | -- | Convert to easily readable JSON-like document. Typically used for |
824 | -- debugging purposes. | 825 | -- debugging purposes. |
825 | ppBEncode :: BEncode -> Doc | 826 | ppBEncode :: BValue -> Doc |
826 | ppBEncode (BInteger i) = int $ fromIntegral i | 827 | ppBEncode (BInteger i) = int $ fromIntegral i |
827 | ppBEncode (BString s) = ppBS s | 828 | ppBEncode (BString s) = ppBS s |
828 | ppBEncode (BList l) = brackets $ hsep $ punctuate comma $ map ppBEncode l | 829 | ppBEncode (BList l) = brackets $ hsep $ punctuate comma $ map ppBEncode l |
diff --git a/tests/properties.hs b/tests/properties.hs index 12f3dfc..0d49445 100644 --- a/tests/properties.hs +++ b/tests/properties.hs | |||
@@ -16,7 +16,7 @@ import Data.BEncode | |||
16 | instance Arbitrary B.ByteString where | 16 | instance Arbitrary B.ByteString where |
17 | arbitrary = fmap B.pack arbitrary | 17 | arbitrary = fmap B.pack arbitrary |
18 | 18 | ||
19 | instance Arbitrary BEncode where | 19 | instance Arbitrary BValue where |
20 | arbitrary = frequency | 20 | arbitrary = frequency |
21 | [ (50, BInteger <$> arbitrary) | 21 | [ (50, BInteger <$> arbitrary) |
22 | , (40, BString <$> arbitrary) | 22 | , (40, BString <$> arbitrary) |
@@ -24,7 +24,7 @@ instance Arbitrary BEncode where | |||
24 | ] | 24 | ] |
25 | 25 | ||
26 | 26 | ||
27 | prop_EncDec :: BEncode -> Bool | 27 | prop_EncDec :: BValue -> Bool |
28 | prop_EncDec x = case decode (L.toStrict (encode x)) of | 28 | prop_EncDec x = case decode (L.toStrict (encode x)) of |
29 | Left _ -> False | 29 | Left _ -> False |
30 | Right x' -> x == x' | 30 | Right x' -> x == x' |