Skip to content

Commit

Permalink
Encode/Decode instances for StrMap (#28)
Browse files Browse the repository at this point in the history
* Encode/Decode instances for StrMap

* Use readStrMap

* Remove redundant checks
  • Loading branch information
jacereda authored and paf31 committed Jul 27, 2017
1 parent 37eb147 commit df66706
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/Data/Foreign/Class.purs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import Data.Bifunctor (lmap)
import Data.Foreign (F, Foreign, ForeignError(ErrorAtIndex), readArray, readBoolean, readChar, readInt, readNumber, readString, toForeign)
import Data.Foreign.NullOrUndefined (NullOrUndefined(..), readNullOrUndefined, undefined)
import Data.Maybe (maybe)
import Data.StrMap as StrMap
import Data.Traversable (sequence)
import Data.Foreign.Internal (readStrMap)

-- | The `Decode` class is used to generate decoding functions
-- | of the form `Foreign -> F a` using `generics-rep` deriving.
Expand Down Expand Up @@ -53,6 +55,9 @@ instance arrayDecode :: Decode a => Decode (Array a) where
readElement :: Int -> Foreign -> F a
readElement i value = mapExcept (lmap (map (ErrorAtIndex i))) (decode value)

instance strMapDecode :: (Decode v) => Decode (StrMap.StrMap v) where
decode = sequence <<< StrMap.mapWithKey (\_ -> decode) <=< readStrMap

-- | The `Encode` class is used to generate encoding functions
-- | of the form `a -> Foreign` using `generics-rep` deriving.
-- |
Expand Down Expand Up @@ -97,3 +102,6 @@ instance decodeNullOrUndefined :: Decode a => Decode (NullOrUndefined a) where

instance encodeNullOrUndefined :: Encode a => Encode (NullOrUndefined a) where
encode (NullOrUndefined a) = maybe undefined encode a

instance strMapEncode :: Encode v => Encode (StrMap.StrMap v) where
encode = toForeign <<< StrMap.mapWithKey (\_ -> encode)
16 changes: 16 additions & 0 deletions src/Data/Foreign/Internal.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Data.Foreign.Internal where

import Prelude

import Data.Foreign (F, Foreign, ForeignError(..), fail, tagOf, unsafeFromForeign)
import Data.StrMap (StrMap)

-- | Test whether a foreign value is a dictionary
isStrMap :: Foreign -> Boolean
isStrMap v = tagOf v == "Object"

-- | Attempt to coerce a foreign value to a StrMap
readStrMap :: Foreign -> F (StrMap Foreign)
readStrMap value
| isStrMap value = pure $ unsafeFromForeign value
| otherwise = fail $ TypeMismatch "StrMap" (tagOf value)
2 changes: 2 additions & 0 deletions test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Data.Foreign.JSON (parseJSON)
import Data.Foreign.NullOrUndefined (NullOrUndefined(..))
import Data.Generic.Rep (class Generic)
import Data.Maybe (Maybe(..))
import Data.StrMap as StrMap
import Data.String (toLower, toUpper)
import Data.Tuple (Tuple(..))
import Global.Unsafe (unsafeStringify)
Expand Down Expand Up @@ -96,4 +97,5 @@ main = do
testRoundTrip (Apple)
testRoundTrip (makeTree 0)
testRoundTrip (makeTree 5)
testRoundTrip (StrMap.fromFoldable [Tuple "one" 1, Tuple "two" 2])
testUnaryConstructorLiteral

0 comments on commit df66706

Please sign in to comment.