summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam T <sta.cs.vsu@gmail.com>2013-04-01 08:08:57 +0400
committerSam T <sta.cs.vsu@gmail.com>2013-04-01 08:08:57 +0400
commitec375e0a115b2bb0211f1a6e08b1782d0e217bc2 (patch)
tree5c51a73ccfa8f50495de0caa949a3ad8fd0b67a9 /src
parent923ad43a0092f0b359d09edc4ac37539437d80cd (diff)
add dict builders
Diffstat (limited to 'src')
-rw-r--r--src/Data/BEncode.hs67
1 files changed, 59 insertions, 8 deletions
diff --git a/src/Data/BEncode.hs b/src/Data/BEncode.hs
index d2cc144..4a80e47 100644
--- a/src/Data/BEncode.hs
+++ b/src/Data/BEncode.hs
@@ -1,28 +1,36 @@
1-- | This module is intented to be imported qualified. 1-- | This module is intented to be imported qualified.
2{-# LANGUAGE FlexibleInstances #-} 2{-# LANGUAGE FlexibleInstances #-}
3module Data.BEncode 3module Data.BEncode
4 ( -- ^ Datatype 4 ( -- * Datatype
5 BEncode(..) 5 BEncode(..)
6 6
7 -- ^ Construction && Destructuring 7 -- * Construction && Destructuring
8 , BEncodable (..), dictAssoc 8 , BEncodable (..), dictAssoc, Result
9 9
10 -- ^ Serialization 10 -- ** Dictionaries
11 -- *** Building
12 , (-->), (-->?), fromAssocs, fromAscAssocs
13
14 -- *** Extraction
15 , reqKey, optKey, (>--), (>--?)
16
17 -- * Serialization
11 , encode, decode 18 , encode, decode
12 19
13 -- ^ Extra 20 -- * Extra
14 , builder, parser, printPretty 21 , builder, parser, decodingError, printPretty
15 22
16 -- ^ Predicates 23 -- * Predicates
17 , isInteger, isString, isList, isDict 24 , isInteger, isString, isList, isDict
18 ) where 25 ) where
19 26
20 27
21import Control.Applicative 28import Control.Applicative
22import Data.Int 29import Data.Int
30import Data.Maybe (mapMaybe)
31import Data.Monoid ((<>))
23import Data.Foldable (foldMap) 32import Data.Foldable (foldMap)
24import Data.Traversable (traverse) 33import Data.Traversable (traverse)
25import Data.Monoid ((<>))
26import Data.Map (Map) 34import Data.Map (Map)
27import qualified Data.Map as M 35import qualified Data.Map as M
28import Data.Attoparsec.ByteString.Char8 (Parser) 36import Data.Attoparsec.ByteString.Char8 (Parser)
@@ -142,7 +150,50 @@ dictAssoc :: [(ByteString, BEncode)] -> BEncode
142dictAssoc = BDict . M.fromList 150dictAssoc = BDict . M.fromList
143{-# INLINE dictAssoc #-} 151{-# INLINE dictAssoc #-}
144 152
153------------------------------------- Building dictionaries --------------------
154data Assoc = Required ByteString BEncode
155 | Optional ByteString (Maybe BEncode)
145 156
157(-->) :: BEncodable a => ByteString -> a -> Assoc
158key --> val = Required key (toBEncode val)
159{-# INLINE (-->) #-}
160
161(-->?) :: BEncodable a => ByteString -> Maybe a -> Assoc
162key -->? mval = Optional key (toBEncode <$> mval)
163{-# INLINE (-->?) #-}
164
165fromAssocs :: [Assoc] -> BEncode
166fromAssocs = BDict . M.fromList . mapMaybe unpackAssoc
167 where
168 unpackAssoc (Required n v) = Just (n, v)
169 unpackAssoc (Optional n (Just v)) = Just (n, v)
170 unpackAssoc (Optional _ Nothing) = Nothing
171
172-- | A faster version of 'fromAssocs'.
173-- Should be used only when keys are sorted by ascending.
174fromAscAssocs :: [Assoc] -> BEncode
175fromAscAssocs = error "fromAscAssocs"
176
177------------------------------------ Extraction --------------------------------
178reqKey :: BEncodable a => Map ByteString BEncode -> ByteString -> Result a
179reqKey d key
180 | Just b <- M.lookup key d = fromBEncode b
181 | otherwise = Left ("required field `" ++ show key ++ " not found")
182
183optKey :: BEncodable a => Map ByteString BEncode -> ByteString -> Result (Maybe a)
184optKey d key
185 | Just b <- M.lookup key d = Just <$> fromBEncode b
186 | otherwise = return Nothing
187
188(>--) :: BEncodable a => Map ByteString BEncode -> ByteString -> Result a
189(>--) = reqKey
190{-# INLINE (>--) #-}
191
192(>--?) :: BEncodable a => Map ByteString BEncode -> ByteString -> Result (Maybe a)
193(>--?) = optKey
194{-# INLINE (>--?) #-}
195
196------------------------------------- Predicates -------------------------------
146isInteger :: BEncode -> Bool 197isInteger :: BEncode -> Bool
147isInteger (BInteger _) = True 198isInteger (BInteger _) = True
148isInteger _ = False 199isInteger _ = False