data-object-json (empty) → 0.0.0
raw patch · 4 files changed
+212/−0 lines, 4 filesdep +attemptdep +basedep +bytestringsetup-changed
Dependencies added: attempt, base, bytestring, bytestring-trie, convertible-text, data-object, json-b, syb
Files
- Data/Object/Json.hs +152/−0
- LICENSE +25/−0
- Setup.lhs +11/−0
- data-object-json.cabal +24/−0
+ Data/Object/Json.hs view
@@ -0,0 +1,152 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE TemplateHaskell #-}+---------------------------------------------------------+--+-- Module : Data.Object.Json+-- Copyright : Michael Snoyman+-- License : BSD3+--+-- Maintainer : Michael Snoyman <michael@snoyman.com>+-- Stability : Stable+-- Portability : portable+---------------------------------------------------------++-- | A simple wrapper around the json-b library which presents values inside+-- 'Object's.+module Data.Object.Json+ ( -- * Types+ JsonDoc (..)+ , JsonScalar (..)+ , JsonObject+ -- * IO+ , readJsonDoc+ , writeJsonDoc+ -- * Serialization+ , JsonDecodeError (..)+ , decode+ , encode+ -- * Specialization+ , toJsonObject+ , fromJsonObject+ ) where++import Data.Object.Text+import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BL+import qualified Data.Trie+import Control.Arrow+import Control.Applicative ((<$>))+import Data.Generics+import Control.Exception+import Data.Attempt+import Data.Convertible.Text++import Text.JSONb.Simple as J+import qualified Text.JSONb.Decode as Decode+import qualified Text.JSONb.Encode as Encode++-- | A fully formed JSON document.+newtype JsonDoc = JsonDoc { unJsonDoc :: BL.ByteString }+ deriving (Show, Eq)++readJsonDoc :: FilePath -> IO JsonDoc+readJsonDoc = fmap JsonDoc . BL.readFile++writeJsonDoc :: FilePath -> JsonDoc -> IO ()+writeJsonDoc fp = BL.writeFile fp . unJsonDoc++-- | Matches the scalar data types used in json-b so we can have proper mapping+-- between the two libraries.+data JsonScalar =+ JsonString BS.ByteString+ | JsonNumber Rational+ | JsonBoolean Bool+ | JsonNull++instance ConvertSuccess JsonScalar Text where+ convertSuccess (JsonString b) = convertSuccess b+ convertSuccess (JsonNumber r) = convertSuccess r+ convertSuccess (JsonBoolean b) = convertSuccess b+ convertSuccess JsonNull = convertSuccess ""+instance ConvertSuccess Text JsonScalar where+ convertSuccess = JsonString . convertSuccess++instance ConvertSuccess JsonScalar String where+ convertSuccess = cs . (cs :: JsonScalar -> Text)+instance ConvertSuccess String JsonScalar where+ convertSuccess = JsonString . cs++instance ConvertSuccess JsonScalar BS.ByteString where+ convertSuccess = cs . (cs :: JsonScalar -> Text)+instance ConvertSuccess BS.ByteString JsonScalar where+ convertSuccess = JsonString . cs++$(let types = [''String, ''BS.ByteString, ''Text]+ in deriveAttempts $+ [(k, ''JsonScalar) | k <- types] +++ [(''JsonScalar, v) | v <- types])++$(deriveSuccessConvs ''BS.ByteString ''JsonScalar+ [''String, ''BS.ByteString, ''Text]+ [''String, ''BS.ByteString, ''Text, ''JsonScalar])++-- | Meant to match closely with the 'JSON' data type. Therefore, uses strict+-- byte strings for keys and the 'JsonScalar' type for scalars.+type JsonObject = Object BS.ByteString JsonScalar++instance ConvertSuccess JSON JsonObject where+ convertSuccess (J.Object trie) =+ Mapping . map (second cs) $ Data.Trie.toList trie+ convertSuccess (J.Array a) = Sequence $ map cs $ a+ convertSuccess (J.String bs) = Scalar $ JsonString bs+ convertSuccess (J.Number r) = Scalar $ JsonNumber r+ convertSuccess (J.Boolean b) = Scalar $ JsonBoolean b+ convertSuccess J.Null = Scalar JsonNull+instance ConvertAttempt JsonObject JSON where+ convertAttempt (Scalar (JsonString bs)) = return $ J.String bs+ convertAttempt (Scalar (JsonNumber r)) = return $ J.Number r+ convertAttempt (Scalar (JsonBoolean b)) = return $ J.Boolean b+ convertAttempt (Scalar JsonNull) = return J.Null+ convertAttempt (Sequence s) = J.Array <$> mapM ca s+ convertAttempt (Mapping m) =+ J.Object . Data.Trie.fromList <$> mapM+ (runKleisli $ second $ Kleisli ca) m++-- | Error type for JSON decoding errors.+newtype JsonDecodeError = JsonDecodeError String+ deriving (Show, Typeable)+instance Exception JsonDecodeError++-- | Decode a lazy bytestring into a 'JsonObject'.+decode :: MonadFailure JsonDecodeError m+ => BL.ByteString+ -> m JsonObject+decode = either (failure . JsonDecodeError . fst)+ (return . toJsonObject)+ . Decode.decode++-- | Encode a 'JsonObject' into a lazy bytestring.+encode :: JsonObject+ -> BL.ByteString+encode = Encode.encode Encode.Compact+ . fromSuccess+ . fromJsonObject++-- | 'convertSuccess' specialized for 'JsonObject's+toJsonObject :: ConvertSuccess a JsonObject => a -> JsonObject+toJsonObject = cs++-- | 'convertAttempt' specialized for 'JsonObject's+fromJsonObject :: ConvertAttempt JsonObject a+ => JsonObject+ -> Attempt a+fromJsonObject = ca++instance ConvertSuccess JsonObject JsonDoc where+ convertSuccess = JsonDoc . encode+instance ConvertAttempt JsonDoc JsonObject where+ convertAttempt = decode . unJsonDoc
+ LICENSE view
@@ -0,0 +1,25 @@+The following license covers this documentation, and the source code, except+where otherwise indicated.++Copyright 2008, Michael Snoyman. All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice, this+ list of conditions and the following disclaimer.++* Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO+EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.lhs view
@@ -0,0 +1,11 @@+#!/usr/bin/env runhaskell++> module Main where+> import Distribution.Simple+> import System.Cmd (system)++> main :: IO ()+> main = defaultMainWithHooks (simpleUserHooks { runTests = runTests' })++> runTests' :: a -> b -> c -> d -> IO ()+> runTests' _ _ _ _ = system "runhaskell Test.hs" >> return ()
+ data-object-json.cabal view
@@ -0,0 +1,24 @@+name: data-object-json+version: 0.0.0+license: BSD3+license-file: LICENSE+author: Michael Snoyman <michael@snoyman.com>+maintainer: Michael Snoyman <michael@snoyman.com>+synopsis: Serialize JSON data to/from Haskell using the data-object library.+category: Text+stability: Stable+cabal-version: >= 1.2+build-type: Simple+homepage: http://github.com/snoyberg/data-object-json/tree/master++library+ build-depends: base >= 4 && < 5,+ json-b >= 0.0.4 && < 0.1,+ bytestring-trie >= 0.1.4 && < 0.2,+ bytestring >= 0.9.1.4 && < 0.10,+ data-object >= 0.2.0 && < 0.3,+ attempt >= 0.2.0 && < 0.3,+ convertible-text >= 0.2.0 && < 0.3,+ syb+ exposed-modules: Data.Object.Json+ ghc-options: -Wall