rest-stringmap (empty) → 0.1.0.0
raw patch · 7 files changed
+304/−0 lines, 7 filesdep +aesondep +basedep +containerssetup-changed
Dependencies added: aeson, base, containers, hashable, hxt, json-schema, text, tostring, unordered-containers
Files
- Setup.hs +2/−0
- rest-stringmap.cabal +32/−0
- src/Rest/StringMap/HashMap/Lazy.hs +62/−0
- src/Rest/StringMap/HashMap/Strict.hs +61/−0
- src/Rest/StringMap/Map/Lazy.hs +57/−0
- src/Rest/StringMap/Map/Strict.hs +57/−0
- src/Rest/StringMap/Util.hs +33/−0
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ rest-stringmap.cabal view
@@ -0,0 +1,32 @@+name: rest-stringmap+version: 0.1.0.0+license: BSD3+synopsis: Maps with stringy keys that can be transcoded to JSON and XML.+description: Maps with stringy keys that can be transcoded to JSON and XML.+author: Silk B.V.+maintainer: code@silk.co+copyright: 2014 Silk B.V.+category: Silk+build-type: Simple+cabal-version: >=1.10++library+ default-language: Haskell2010+ ghc-options: -Wall+ hs-source-dirs: src+ exposed-modules:+ Rest.StringMap.HashMap.Strict+ Rest.StringMap.HashMap.Lazy+ Rest.StringMap.Map.Lazy+ Rest.StringMap.Map.Strict+ Rest.StringMap.Util+ build-depends:+ base >= 4.6 && < 4.8+ , aeson == 0.7.*+ , containers == 0.5.*+ , hashable == 1.2.*+ , hxt == 9.3.*+ , json-schema == 0.4.*+ , text >= 0.10 && < 1.2+ , tostring == 0.2.*+ , unordered-containers == 0.2.*
+ src/Rest/StringMap/HashMap/Lazy.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE+ DeriveDataTypeable+ , FlexibleInstances+ , OverlappingInstances+ , ScopedTypeVariables+ #-}+module Rest.StringMap.HashMap.Lazy+ ( StringHashMap+ , fromHashMap+ , toHashMap+ , fromList+ , toList+ ) where++import Data.Aeson+import Data.HashMap.Strict (HashMap)+import Data.Hashable+import Data.JSON.Schema+import Data.String+import Data.String.ToString+import Data.Typeable+import Text.XML.HXT.Arrow.Pickle+import qualified Data.HashMap.Lazy as H++import Rest.StringMap.Util++newtype StringHashMap a b = StringHashMap { unH :: HashMap a b }+ deriving (Eq, Show, Typeable)++fromHashMap :: HashMap a b -> StringHashMap a b+fromHashMap = StringHashMap++toHashMap :: StringHashMap a b -> HashMap a b+toHashMap = unH++fromList :: (Eq a, Hashable a) => [(a, b)] -> StringHashMap a b+fromList = StringHashMap . H.fromList++toList :: StringHashMap a b -> [(a, b)]+toList = H.toList . unH++-- | This is used with the assumption that a = b => f a = f b+mapKeys :: (Hashable l, Eq l) => (k -> l) -> StringHashMap k v -> StringHashMap l v+mapKeys f = StringHashMap . H.foldlWithKey' (\h k v -> H.insert (f k) v h) H.empty . unH++-- | Base case since XmlPickler expects strings+instance XmlPickler b => XmlPickler (StringHashMap String b) where+ xpickle = pickleStringMap fromList toList++-- | General case+instance (Eq a, Hashable a, IsString a, ToString a, XmlPickler b) => XmlPickler (StringHashMap a b) where+ xpickle = pickleMap mapKeys mapKeys++instance (ToString a, ToJSON b) => ToJSON (StringHashMap a b) where+ toJSON = mapToJSON mapKeys++instance (Hashable a, Eq a, IsString a, FromJSON b) => FromJSON (StringHashMap a b) where+ parseJSON = mapParseJSON mapKeys++instance JSONSchema b => JSONSchema (StringHashMap a b) where+ schema _ = mapSchema (Proxy :: Proxy b)+
+ src/Rest/StringMap/HashMap/Strict.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE+ DeriveDataTypeable+ , FlexibleInstances+ , OverlappingInstances+ , ScopedTypeVariables+ #-}+module Rest.StringMap.HashMap.Strict+ ( StringHashMap+ , fromHashMap+ , toHashMap+ , fromList+ , toList+ ) where++import Data.Aeson+import Data.HashMap.Strict (HashMap)+import Data.Hashable+import Data.JSON.Schema+import Data.String+import Data.String.ToString+import Data.Typeable+import Text.XML.HXT.Arrow.Pickle+import qualified Data.HashMap.Strict as H++import Rest.StringMap.Util++newtype StringHashMap a b = StringHashMap { unH :: HashMap a b }+ deriving (Eq, Show, Typeable)++fromHashMap :: HashMap a b -> StringHashMap a b+fromHashMap = StringHashMap++toHashMap :: StringHashMap a b -> HashMap a b+toHashMap = unH++fromList :: (Eq a, Hashable a) => [(a, b)] -> StringHashMap a b+fromList = StringHashMap . H.fromList++toList :: StringHashMap a b -> [(a, b)]+toList = H.toList . unH++-- | This is used with the assumption that a = b => f a = f b+mapKeys :: (Hashable l, Eq l) => (k -> l) -> StringHashMap k v -> StringHashMap l v+mapKeys f = StringHashMap . H.foldlWithKey' (\h k v -> H.insert (f k) v h) H.empty . unH++-- | Base case since XmlPickler expects strings+instance XmlPickler b => XmlPickler (StringHashMap String b) where+ xpickle = pickleStringMap fromList toList++-- | General case+instance (Eq a, Hashable a, IsString a, ToString a, XmlPickler b) => XmlPickler (StringHashMap a b) where+ xpickle = pickleMap mapKeys mapKeys++instance (ToString a, ToJSON b) => ToJSON (StringHashMap a b) where+ toJSON = mapToJSON mapKeys++instance (Hashable a, Eq a, IsString a, FromJSON b) => FromJSON (StringHashMap a b) where+ parseJSON = mapParseJSON mapKeys++instance JSONSchema b => JSONSchema (StringHashMap a b) where+ schema _ = mapSchema (Proxy :: Proxy b)
+ src/Rest/StringMap/Map/Lazy.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE+ DeriveDataTypeable+ , FlexibleInstances+ , OverlappingInstances+ , ScopedTypeVariables+ #-}+module Rest.StringMap.Map.Lazy+ ( StringMap+ , fromMap+ , toMap+ , toList+ , fromList+ ) where++import Data.Aeson+import Data.JSON.Schema+import Data.Map (Map)+import Data.String+import Data.String.ToString+import Data.Typeable+import Text.XML.HXT.Arrow.Pickle+import qualified Data.Map as M++import Rest.StringMap.Util++newtype StringMap a b = StringMap { unM :: Map a b }+ deriving (Eq, Show, Typeable)++fromMap :: Map a b -> StringMap a b+fromMap = StringMap++toMap :: StringMap a b -> Map a b+toMap = unM++fromList :: Ord a => [(a,b)] -> StringMap a b+fromList = StringMap . M.fromList++toList :: StringMap a b -> [(a, b)]+toList = M.toList . unM++mapKeys :: Ord l => (k -> l) -> StringMap k v -> StringMap l v+mapKeys f = StringMap . M.mapKeys f . unM++instance XmlPickler b => XmlPickler (StringMap String b) where+ xpickle = pickleStringMap fromList toList++instance (Ord a, IsString a, ToString a, XmlPickler b) => XmlPickler (StringMap a b) where+ xpickle = pickleMap mapKeys mapKeys++instance (ToString a, ToJSON b) => ToJSON (StringMap a b) where+ toJSON = toJSON . M.mapKeys toString . unM++instance (Ord a, IsString a, FromJSON b) => FromJSON (StringMap a b) where+ parseJSON = fmap (StringMap . M.mapKeys fromString) . parseJSON++instance JSONSchema b => JSONSchema (StringMap a b) where+ schema _ = mapSchema (Proxy :: Proxy b)
+ src/Rest/StringMap/Map/Strict.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE+ DeriveDataTypeable+ , FlexibleInstances+ , OverlappingInstances+ , ScopedTypeVariables+ #-}+module Rest.StringMap.Map.Strict+ ( StringMap+ , fromMap+ , toMap+ , toList+ , fromList+ ) where++import Data.Aeson+import Data.JSON.Schema+import Data.Map.Strict (Map)+import Data.String+import Data.String.ToString+import Data.Typeable+import Text.XML.HXT.Arrow.Pickle+import qualified Data.Map.Strict as M++import Rest.StringMap.Util++newtype StringMap a b = StringMap { unM :: Map a b }+ deriving (Eq, Show, Typeable)++fromMap :: Map a b -> StringMap a b+fromMap = StringMap++toMap :: StringMap a b -> Map a b+toMap = unM++fromList :: Ord a => [(a,b)] -> StringMap a b+fromList = StringMap . M.fromList++toList :: StringMap a b -> [(a, b)]+toList = M.toList . unM++mapKeys :: Ord l => (k -> l) -> StringMap k v -> StringMap l v+mapKeys f = StringMap . M.mapKeys f . unM++instance XmlPickler b => XmlPickler (StringMap String b) where+ xpickle = pickleStringMap fromList toList++instance (Ord a, IsString a, ToString a, XmlPickler b) => XmlPickler (StringMap a b) where+ xpickle = pickleMap mapKeys mapKeys++instance (ToString a, ToJSON b) => ToJSON (StringMap a b) where+ toJSON = toJSON . M.mapKeys toString . unM++instance (Ord a, IsString a, FromJSON b) => FromJSON (StringMap a b) where+ parseJSON = fmap (StringMap . M.mapKeys fromString) . parseJSON++instance JSONSchema b => JSONSchema (StringMap a b) where+ schema _ = mapSchema (Proxy :: Proxy b)
+ src/Rest/StringMap/Util.hs view
@@ -0,0 +1,33 @@+module Rest.StringMap.Util+ ( pickleStringMap+ , pickleMap+ , mapSchema+ , mapToJSON+ , mapParseJSON+ ) where++import Data.Aeson.Types+import Data.JSON.Schema (JSONSchema, Schema, schema)+import Data.JSON.Schema.Combinators (field)+import Data.Proxy (Proxy)+import Data.String (IsString (..))+import Data.String.ToString (ToString (..))+import Text.XML.HXT.Arrow.Pickle (PU, XmlPickler, xpElem, xpList, xpPair, xpTextAttr, xpWrap, xpickle)++pickleStringMap :: XmlPickler b => ([(String, b)] -> m) -> (m -> [(String, b)]) -> PU m+pickleStringMap fromList toList =+ xpElem "map"+ $ xpWrap (fromList, toList)+ $ xpList (xpElem "value" (xpPair (xpTextAttr "key") xpickle))++pickleMap :: (XmlPickler m, ToString k, IsString k) => ((String -> k) -> m -> m') -> ((k -> String) -> m' -> m) -> PU m'+pickleMap mapKeys mapKeys' = xpWrap (mapKeys fromString, mapKeys' toString) xpickle++mapSchema :: JSONSchema a => Proxy a -> Schema+mapSchema = field "key" False . schema++mapToJSON :: (ToString a, ToJSON m) => ((a -> String) -> m' -> m) -> m' -> Value+mapToJSON mapKeys = toJSON . mapKeys toString++mapParseJSON :: (FromJSON m, IsString k) => ((String -> k) -> m -> m') -> Value -> Parser m'+mapParseJSON mapKeys = fmap (mapKeys fromString) . parseJSON