packages feed

RJson 0.3.6 → 0.3.7

raw patch · 3 files changed

+61/−29 lines, 3 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Text.RJson: instance [overlap ok] (Data ctx a[a28u], Data ctx b[a28v], Sat (ctx (Union a[a28u] b[a28v]))) => Data ctx (Union a[a28u] b[a28v])
- Text.RJson: instance [overlap ok] (FromJson t) => Sat (FromJsonD t)
- Text.RJson: instance [overlap ok] (ToJson t) => Sat (ToJsonD t)
- Text.RJson: instance [overlap ok] (TranslateField t) => Sat (TranslateFieldD t)
- Text.RJson: instance [overlap ok] (Typeable a) => TranslateField a
+ Text.RJson: cond :: (a -> Bool) -> (a -> b) -> (a -> b) -> a -> b
+ Text.RJson: instance [overlap ok] (Data ctx a[a27X], Data ctx b[a27Y], Sat (ctx (Union a[a27X] b[a27Y]))) => Data ctx (Union a[a27X] b[a27Y])
+ Text.RJson: instance [overlap ok] FromJson t => Sat (FromJsonD t)
+ Text.RJson: instance [overlap ok] ToJson t => Sat (ToJsonD t)
+ Text.RJson: instance [overlap ok] TranslateField t => Sat (TranslateFieldD t)
+ Text.RJson: instance [overlap ok] Typeable a => TranslateField a
- Text.RJson: arrayAppend :: (ToJson a) => a -> [JsonData]
+ Text.RJson: arrayAppend :: ToJson a => a -> [JsonData]
- Text.RJson: arrayPrepend :: (ToJson a) => a -> [JsonData]
+ Text.RJson: arrayPrepend :: ToJson a => a -> [JsonData]
- Text.RJson: class (TranslateField a) => FromJson a
+ Text.RJson: class TranslateField a => FromJson a
- Text.RJson: class (TranslateField a) => ToJson a
+ Text.RJson: class TranslateField a => ToJson a
- Text.RJson: exclude :: (ToJson a) => a -> String -> Bool
+ Text.RJson: exclude :: ToJson a => a -> String -> Bool
- Text.RJson: fromJson :: (FromJson a) => a -> JsonData -> Either String a
+ Text.RJson: fromJson :: FromJson a => a -> JsonData -> Either String a
- Text.RJson: fromJsonByteString :: (FromJson a) => a -> ByteString -> Either String a
+ Text.RJson: fromJsonByteString :: FromJson a => a -> ByteString -> Either String a
- Text.RJson: fromJsonString :: (FromJson a) => a -> String -> Either String a
+ Text.RJson: fromJsonString :: FromJson a => a -> String -> Either String a
- Text.RJson: objectDefaults :: (FromJson a) => a -> Map String JsonData
+ Text.RJson: objectDefaults :: FromJson a => a -> Map String JsonData
- Text.RJson: objectExtras :: (ToJson a) => a -> [(String, JsonData)]
+ Text.RJson: objectExtras :: ToJson a => a -> [(String, JsonData)]
- Text.RJson: toJson :: (ToJson a) => a -> JsonData
+ Text.RJson: toJson :: ToJson a => a -> JsonData
- Text.RJson: toJsonString :: (ToJson a) => a -> String
+ Text.RJson: toJsonString :: ToJson a => a -> String
- Text.RJson: translateField :: (TranslateField a) => a -> String -> String
+ Text.RJson: translateField :: TranslateField a => a -> String -> String

Files

README view
@@ -1,11 +1,13 @@ ************************************************************************-* RJSon 0.3.6                                                          *-* Author: Alex Drummond                                                *-*                                                                      *-* Thanks to Dustin DeWeese and Audrey Tang for patches fixing bugs in  * -* the parser.                                                          *-* Thanks to Adam Langley for a patch fixing the lack of support for    *-* null JSON values.                                                    *+| RJSon 0.3.7                                                          |+| Author: Alex Drummond                                                |+|                                                                      |+| Thanks to Dustin DeWeese and Audrey Tang for patches fixing bugs in  | +| the parser.                                                          |+| Thanks to Adam Langley for a patch fixing the lack of support for    |+| null JSON values.                                                    |+| Thanks to Maarten for fixing an inconsistency in the behavior of    |+| serialization/parsing.                                               | ************************************************************************  This is some documentation on how to use the RJson library.  I wrote a@@ -105,11 +107,12 @@  The JsonData type has the following definition: -    data JsonData = JDString String                          |-                    JDNumber Double                          |-                    JDArray [JsonData]                       |-                    JDBool Bool                              |-                    JDObject (Data.Map.Map String JsonData)+    data JsonData = JDString String                   |+                    JDNumber Double                   |+                    JDArray [JsonData]                |+                    JDBool Bool                       |+                    JDNull                            |+                    JDObject (M.Map String JsonData)  You can implement custom serialization and deserialization behavior by adding instances to the ToJson and FromJson classes respectively.
RJson.cabal view
@@ -1,5 +1,5 @@ Name:          RJson-Version:       0.3.6+Version:       0.3.7 Cabal-Version: >= 1.2 License:       BSD3 License-File:  LICENSE
Text/RJson.hs view
@@ -34,7 +34,8 @@                    firstCharToUpper,                    firstCharToLower,                    Union(..), Union3, Union4, Union5, Union6,-                   Union7,Union8,Union9,Union10)+                   Union7,Union8,Union9,Union10,+                   cond) where  import Data.Generics.SYB.WithClass.Basics@@ -410,9 +411,6 @@     fromJson _ (JDBool b) = Right b     fromJson _ _          = Left "Bad fromJson conversion: Non-boolean to 'Bool'" -isRight (Right _) = True-isRight _         = False-fromRight (Right x) = x -- TODO: Use monads instead of 'ifs' if possible (funky type errors -- which I haven't figured out yet, something to do with monomorphism -- in let bindings vs. lambda abstraction?).@@ -541,31 +539,45 @@            Left e -> throwError e            Right x -> return x + genericFromJson :: (Data FromJsonD a, FromJson a, TranslateField a) => a -> JsonData -> Either String a genericFromJson dummy (JDArray l) =     case datarep (dataTypeOf fromJsonProxy dummy) of-      AlgRep (c:_) ->-          evalState (runErrorT (fromConstrM fromJsonProxy m1 c)) (tail l)+      AlgRep ccs@(c:cs) -> evalArrayConstr ccs+			where+				evalArrayConstr = tryHead err . dropWhile isLeft . map es+				es :: (Data FromJsonD a, FromJson a) => Constr -> Either String a+				es c = evalState (runErrorT (fromConstrM fromJsonProxy m1 c)) (tryTail l)+				tryTail = cond null (const []) tail+				tryHead def = cond null (const def) head+				err = Left "Bad fromJson conversion: Type with no constructors!"       AlgRep _     -> Left "Bad fromJson conversion: Type with no constructors!"       _            -> Left "Bad fromJson conversion: Non-algebraic datatype given to 'genericFromJson'" genericFromJson dummy (JDObject m) =     case datarep (dataTypeOf fromJsonProxy dummy) of-      AlgRep (c:_) ->-          case constrFields c of-            [] -> Left $ "Bad fromJson conversion: Attempt to convert JDObect to a non-record algebraic type"-            -- TODO:-            -- Can't use fromConstrM because we need to get dummy values of the-            -- appropriate type for each argument of the constructor. This is unfortunate,-            -- becuase it means that we get runtime errors for records with strict fields.-            fs -> evalState (runErrorT (gmapM fromJsonProxy (m2 (objectDefaultsD dict dummy) (translateFieldD'' dict dummy)) (fromConstr fromJsonProxy c))) (m, fs)-      AlgRep _     -> Left "Bad fromJson conversion: Type with no constructors!"-      _            -> Left "Bad fromJson conversion: Non-algebraic datatype given to 'genericFromJson'"+      AlgRep cs@(_:_) -> evalConstrs dummy m cs+      _			-> Left "Bad fromJson conversion: Non-algebraic datatype given to 'genericFromJson'" genericFromJson dummy jsondata =     case datarep (dataTypeOf fromJsonProxy dummy) of         AlgRep [c] -> evalState (runErrorT (gmapM fromJsonProxy (m3 jsondata) (fromConstr fromJsonProxy c))) 0         AlgRep _ -> Left "Bad fromJson conversion: Expecting JSON object or array; did not attempt automatic boxing because type has more than one constructor." genericFromJson _ _ = Left "Bad fromJson conversion: Expecting JSON object or array" +evalConstrs :: (Data FromJsonD a, FromJson a) => a -> M.Map String JsonData -> [Constr] -> Either [Char] a+evalConstrs dummy m = tryHead err . dropWhile isLeft . map (evalConstr dummy m)+	where+		tryHead def = cond null (const def) head+		err = Left "Bad fromJson conversion: Type with no constructors!"++evalConstr :: (Data FromJsonD a, FromJson a) => a -> M.Map String JsonData -> Constr -> Either [Char] a+evalConstr dummy m c = case constrFields c of+    [] -> Left $ "Bad fromJson conversion: Attempt to convert JDObect to a non-record algebraic type"+    -- TODO:+    -- Can't use fromConstrM because we need to get dummy values of the+    -- appropriate type for each argument of the constructor. This is unfortunate,+    -- becuase it means that we get runtime errors for records with strict fields.+    fs -> evalState (runErrorT (gmapM fromJsonProxy (m2 (objectDefaultsD dict dummy) (translateFieldD'' dict dummy)) (fromConstr fromJsonProxy c))) (m, fs)+ constrNames :: (Data FromJsonD a, Data TranslateFieldD a) => a -> [String] constrNames x = map showConstr (dataTypeConstrs (dataTypeOf fromJsonProxy x)) @@ -800,3 +812,20 @@ firstCharToLower :: String -> String firstCharToLower "" = "" firstCharToLower (c:cs) = (toLower c) : cs++isLeft :: Either a b -> Bool+isLeft (Left _) = True+isLeft _        = False++isRight :: Either a b -> Bool+isRight (Right _) = True+isRight _         = False++fromLeft :: Either a b -> a+fromLeft (Left x) = x+fromRight :: Either a b -> b+fromRight (Right x) = x++cond :: (a -> Bool) -> (a -> b) -> (a -> b) -> a -> b+cond p th el a = if p a then th a else el a+