packages feed

Jdh (empty) → 0.1.0.0

raw patch · 7 files changed

+478/−0 lines, 7 filesdep +basesetup-changed

Dependencies added: base

Files

+ Data/Jdh/Json.hs view
@@ -0,0 +1,30 @@+{-|+Module      : Data.Jdh.Json+Description : A module for small Json Value Types+License     : MIT+Maintainer  : brunoczim@gmail.com+Stability   : experimental+Portability : OS-Independent++This module contains the small version for Json Values. Example: A JSInt is implemented as Int.+Although the module is destinated for small values (Int, Float and String), all functions from Data.Json.Generic are avaible as generics. This module defines a type synonymous and two functions for encoding and decoding JSValue of this type.+-}+module Data.Jdh.Json(+    module G,+    Json,+    encode,+    decode+) where+import Data.Jdh.Json.Generic as G++-- | A synonymous type for (JSValue Int Float String)+type Json = JSValue Int Float String++-- | A function for encoding that specifies the types of JSValue to be the same as Json type. If the first argument is passed as false, the resulting string is condensed, otherwise, it will contain whitespaces as indentation and line breaks.+encode :: Bool -> Json -> String+encode True = G.prettify+encode False = G.stringify++-- | A function for decoding that specifies the types of JSValue to be the same as Json type.+decode :: String -> [(Json, String)]+decode = G.parse
+ Data/Jdh/Json/Big.hs view
@@ -0,0 +1,31 @@+{-|+Module      : Data.Jdh.Json.Big+Description : A module for big Json Value Types+License     : MIT+Maintainer  : brunoczim@gmail.com+Stability   : experimental+Portability : OS-Independent++This module contains the big version for Json Values. Example: A JSInt is implemented as Integer.+Although the module is destinated for big values (Integer, Double and String), all functions from Data.Json.Generic are avaible as generics. This module defines a type synonymous and two functions for encoding and decoding JSValue of this type.+-}+module Data.Jdh.Json.Big(+    module G,+    Json,+    encode,+    decode+) where+import Data.Jdh.Json.Generic as G+++-- | A synonymous type for (JSValue Integer Double String)+type Json = JSValue Integer Double String++-- | A function for encoding that specifies the types of JSValue to be the same as Json type. If the first argument is passed as false, the resulting string is condensed, otherwise, it will contain whitespaces as indentation and line breaks.+encode :: Bool -> Json -> String+encode True = G.prettify+encode False = G.stringify++-- | A function for decoding that specifies the types of JSValue to be the same as Json type.+decode :: String -> [(Json, String)]+decode = G.parse
+ Data/Jdh/Json/Generic.hs view
@@ -0,0 +1,305 @@+{-|+Module      : Data.Jdh.Json.Generic+Description : A module for generic Json Value Types+License     : MIT+Maintainer  : brunoczim@gmail.com+Stability   : experimental+Portability : OS-Independent++This module contains the generic version for Json Values. Example: A JSInt can be an Int but also an Integer.+This module also provides the functions for JSON encoding and decoding.+-}+module Data.Jdh.Json.Generic(+    JSValue,+    JSProperty,+    getInt,+    getReal,+    getBool,+    getStr,+    getArray,+    getObj,+    isNull,+    isInt,+    isReal,+    isBool,+    isStr,+    isArray,+    isObj,+    fromNull,+    fromInt,+    fromReal,+    fromBool,+    fromStr,+    fromArray,+    fromProps,+    (=:),+    stringify,+    prettify,+    parse,+    getProp+) where+import Data.String as S+import Data.Char as C++-- | The data JSValue holds any possible JSON Value. Note that its types can be flexible, a JSInt may be of any Integral type, JSReal of any Fractional type, etc.+data JSValue int real str+    = JSNull+    | JSInt {+        -- | Returns the unboxed Integral value of JSValue+        getInt :: int+    }+    | JSReal {+        -- | Returns the unboxed Fractional value of JSValue+        getReal :: real+    }+    | JSBoolean {+        -- | Returns the unboxed Bool value of JSValue+        getBool :: Bool+    }+    | JSString {+        -- | Returns the unboxed IsString value of JSValue+        getStr :: str+    }+    | JSArray {+        -- | Returns the unboxed [JSValue] value of JSValue+        getArray :: [JSValue int real str]+    }+    | JSObject {+        -- | Returns the unboxed [(IsString, JSValue)] value of JSValue+        getObj :: [(str, JSValue int real str)]+    }++-- | The JSProperty type is a synonymous for a tuple containing a String-like value and a JSValue. It represents an object Property.+type JSProperty int real str = (str, JSValue int real str)+++-- | This function checks if a JSValue is null (constructed with JSNull constructor).+isNull :: JSValue a b c -> Bool+isNull JSNull = True+isNull _ = False++-- | This function checks if a JSValue is an integer (constructed with JSInt constructor).+isInt :: JSValue a b c -> Bool+isInt (JSInt _ ) = True+isInt _ = False++-- | This function checks if a JSValue is floating point number (constructed with JSReal constructor).+isReal :: JSValue a b c -> Bool+isReal (JSReal _ ) = True+isReal _ = False++-- | This function checks if a JSValue is boolean (constructed with JSBoolean constructor).+isBool :: JSValue a b c -> Bool+isBool (JSBoolean _ ) = True+isBool _ = False++-- | This function checks if a JSValue is string (constructed with JSString constructor).+isStr :: JSValue a b c -> Bool+isStr (JSString _ ) = True+isStr _ = False++-- | This function checks if a JSValue is array (constructed with JSArray constructor).+isArray :: JSValue a b c -> Bool+isArray (JSArray _ ) = True+isArray _ = False++-- | This function checks if a JSValue is object (constructed with JSObject constructor).+isObj :: JSValue a b c -> Bool+isObj (JSObject _ ) = True+isObj _ = False++-- | Creates a null JSValue (no arguments).+fromNull :: (Integral a, Fractional b, S.IsString c) => JSValue a b c+fromNull = JSNull++-- | Creates a JSValue from an Integral value.+fromInt :: (Integral a, Fractional b, S.IsString c) => a -> JSValue a b c+fromInt = JSInt++-- | Creates a JSValue from a Fractional value.+fromReal :: (Integral a, Fractional b, S.IsString c) => b -> JSValue a b c+fromReal = JSReal++-- | Creates a JSValue from a Bool value.+fromBool :: (Integral a, Fractional b, S.IsString c) => Bool -> JSValue a b c+fromBool = JSBoolean++-- | Creates a JSValue from a IsString value.+fromStr :: (Integral a, Fractional b, S.IsString c) => c -> JSValue a b c+fromStr = JSString++-- | Creates an Array JSValue from a list of JSValue.+fromArray :: (Integral a, Fractional b, S.IsString c) => [JSValue a b c] -> JSValue a b c+fromArray = JSArray++-- | Creates an Object JSValue from a list of properties relation (a (IsString,JSValue) tuple).+fromProps :: (Integral a, Fractional b, S.IsString c) => [JSProperty a b c] -> JSValue a b c+fromProps = JSObject++-- | An operator that creates a JSPropery value. Use it as property =: value.+infixl 5 =:+(=:) :: (Integral a, Fractional b, S.IsString c) => c -> JSValue a b c -> JSProperty a b c+propname =: propval = (propname, propval)++++tabsize :: String+tabsize = replicate 4 ' '++-- | Encodes a JSValue into a String. Condenses the String; no whitespace will be included.+stringify :: (Integral a, Fractional b, S.IsString c, Show a, Show b, Show c) => JSValue a b c -> String+stringify JSNull = "null"+stringify (JSInt int) = show int+stringify (JSReal real) = show real+stringify (JSBoolean bool) = if bool then "true" else "false"+stringify (JSString str ) = show str+stringify (JSArray arr) = '[' : handle arr where+    handle [] = "]"+    handle [x] = stringify x ++ "]"+    handle (x:xs) = stringify x ++ "," ++ handle xs+stringify (JSObject obj) = '{' : handle obj where+    handle [] = "}"+    handle [(pname, pval)] = show pname ++ (':': stringify pval) ++ "}"+    handle ((pname, pval):xs) = show pname ++ (':': stringify pval) ++ "," ++ handle xs++-- | Encodes a JSValue into a String. Prettifies the output with indentation and linefeeds.+prettify :: (Integral a, Fractional b, S.IsString c, Show a, Show b, Show c) => JSValue a b c -> String+prettify x = prettify' x False ""++prettify' :: (Integral a, Fractional b, S.IsString c, Show a, Show b, Show c) => JSValue a b c -> Bool -> String -> String+prettify' JSNull False tab = tab ++ "null"+prettify' JSNull True _ = "null"+prettify' (JSInt int) False tab = tab ++ show int+prettify' (JSInt int) True _ = show int+prettify' (JSReal real) False tab = tab ++ show real+prettify' (JSReal real) True _ = show real+prettify' (JSBoolean bool) False tab = tab ++ (if bool then "true" else "false")+prettify' (JSBoolean bool) True _ = if bool then "true" else "false"+prettify' (JSString str ) False tab = tab ++ show str+prettify' (JSString str ) True _ = show str+prettify' (JSArray arr) cameFromObj tab = if not cameFromObj+    then tab ++ "[\n" ++ handle arr+    else "[\n" ++ handle arr+    where+        handle [] = tab ++ "]"+        handle [x] = prettify' x False (tab++tabsize) ++ "\n" ++ tab ++ "]"+        handle (x:xs) = prettify' x False (tab++tabsize) ++ ",\n" ++ handle xs+prettify' (JSObject obj) cameFromObj tab = if not cameFromObj+    then tab ++ "{\n" ++ handle obj+    else "{\n" ++ handle obj+    where+        handle [] = tab ++ "}"+        handle [(pname, pval)] = tab ++ tabsize ++ show pname ++ ": "+            ++ prettify' pval True (tab ++ tabsize) ++ "\n" ++ tab ++ "}"+        handle ((pname, pval):xs) = tab ++ tabsize ++ show pname ++ ": "+            ++ prettify' pval True (tab ++ tabsize) ++ ",\n" ++ handle xs++skipWhitespace :: String -> String+skipWhitespace = dropWhile (`elem` " \n\r\t")++-- | Parses an encoded JSON string into JSValues.+parse :: (Integral a, Fractional b, S.IsString c, Read a, Read b, Read c) => String -> [(JSValue a b c, String)]+parse [] = []+parse string+    | null skipped = []+    | C.isDigit $ head skipped = if '.' `elem` takeWhile (\ x -> C.isDigit x || x == '.') skipped+        then+            let readtry = reads skipped :: (Fractional b, Read b) => [(b, String)]+            in if null readtry+                then []+                else let [(number, remains)] = readtry in [(JSReal number, remains)]+        else+            let readtry = reads skipped :: (Integral a, Read a) => [(a, String)]+            in if null readtry+                then []+                else let [(number, remains)] = readtry in [(JSInt number, remains)]+    | head skipped == '"' = let readtry = reads skipped in if null readtry+        then []+        else+            let [(str, remains)] = readtry+            in [(JSString str, remains)]+    | head skipped == 'n' = [(JSNull, drop 4 skipped) | length skipped >= 4 && take 4 skipped == "null"]+    | head skipped == 't' = [(JSBoolean True, drop 4 skipped) | length skipped >= 4 && take 4 skipped == "true"]+    | head skipped == 'f' = [(JSBoolean False, drop 5 skipped) | length skipped >= 5 && take 5 skipped == "false"]+    | head skipped == '[' =+        let str = skipWhitespace (drop 1 skipped) in if null str then [] else if head str == ']'+            then [(JSArray [], drop 1 str)]+            else+                let handle [(tillnow, remains)] = if null readRem then [] else+                        let [(parsed, remains')] = readRem+                            skippedRem = skipWhitespace remains'+                        in if null skippedRem then [] else if head skippedRem == ']'+                            then [(tillnow ++ [parsed], drop 1 skippedRem)]+                            else if head skippedRem == ','+                                then handle [(tillnow ++ [parsed], skipWhitespace $ drop 1 skippedRem)]+                                else []+                                where+                                    readRem = parse remains+                    handle _ = []+                    answer = handle [([], str)]+                in if null answer+                    then []+                    else+                        let [(arr, remstr)] = answer+                        in [(JSArray arr, remstr)]+    | head skipped == '{' = let str = skipWhitespace (drop 1 skipped) in if null str then [] else if head str == '}'+        then [(JSObject [], drop 1 str)]+        else+            let handle [(tillnow, remains)] = if null readRemKey then [] else+                    let [(parsedkey, remainskey)] = readRemKey+                        skippedRemKey = skipWhitespace remainskey+                    in if null skippedRemKey || head skippedRemKey /= ':' then [] else+                        let readRemVal = parse $ skipWhitespace $ drop 1 remainskey+                        in if null readRemVal then [] else+                            let [(parsedVal, remainsVal)] = readRemVal+                                skippedRemVal = skipWhitespace remainsVal+                            in if null skippedRemVal then [] else if head skippedRemVal == '}'+                                then [(tillnow ++ [parsedkey =: parsedVal], drop 1 skippedRemVal)]+                                else if head skippedRemVal == ','+                                    then handle [(tillnow ++ [parsedkey =: parsedVal], skipWhitespace $ drop 1 skippedRemVal)]+                                    else []+                                    where+                                        readRemKey = reads remains+                handle _ = []+                answer = handle [([], str)]+            in if null answer+                then []+                else+                    let [(arr, remstr)] = answer+                    in [(JSObject arr, remstr)]+    | otherwise = []+    where+        skipped = skipWhitespace string++-- | Returns a given property from a object. Note that this function returns type of Maybe (JSValue a b c); if the property is not found, returns Nothing+getProp :: (Integral a, Fractional b, S.IsString c, Eq c) => c -> JSValue a b c -> Maybe (JSValue a b c)+getProp property (JSObject ((propname, val):xs)) = if propname == property+    then Just val+    else getProp property (JSObject xs)+getProp _ _ = Nothing+++-- | JSValue Implements the Show class, the method show is implemented with prettify.+instance (Integral a, Fractional b, S.IsString c, Show a, Show b, Show c) => Show (JSValue a b c ) where+    show = prettify++-- | JSValue Implements the Read class, the method readsPrec is implemented with parse.+instance (Integral a, Fractional b, S.IsString c, Read a, Read b, Read c) => Read (JSValue a b c ) where+    readsPrec _ = parse++-- | JSValue Implements the Eq class, the method == is implemented comparing the respectives JSValue types. Example: JSBooleans are compared only with JSBooleans, comparing other types will always return False+instance (Integral a, Fractional b, S.IsString c, Eq a, Eq b, Eq c) => Eq (JSValue a b c) where+    JSNull == JSNull = True+    JSNull == _ = False+    (JSBoolean a) == (JSBoolean b) = a == b+    (JSBoolean _) == _ = False+    (JSString a) == (JSString b) = a == b+    (JSString _) == _ = False+    (JSArray a) == (JSArray b) = a == b+    (JSArray _) == _ = False+    (JSInt a) == (JSInt b) = a == b+    (JSInt _) == _ = False+    (JSReal a) == (JSReal b) = a == b+    (JSReal _) == _ = False+    (JSObject a) == (JSObject b) = a == b+    (JSObject _) == _ = False
+ Jdh.cabal view
@@ -0,0 +1,72 @@+-- Initial Jdh.cabal generated by cabal init.  For further documentation,+-- see http://haskell.org/cabal/users-guide/++-- The name of the package.+name:                Jdh++-- The package version.  See the Haskell package versioning policy (PVP)+-- for standards guiding when and how versions should be incremented.+-- http://www.haskell.org/haskellwiki/Package_versioning_policy+-- PVP summary:      +-+------- breaking API changes+--                   | | +----- non-breaking API additions+--                   | | | +--- code changes with no API change+version:             0.1.0.0++-- A short (one-line) description of the package.+synopsis:            A Json implementation for Haskell, with JavaScript Values and Encoding/Decoding++-- A longer description of the package.+-- description:++-- URL for the project homepage or repository.+homepage:            https://github.com/brunoczim/Json-Data-for-Haskell+++-- The license under which the package is released.+license:             MIT++-- The file containing the license text.+license-file:        LICENSE++-- The package author(s).+author:              Bruno Corrêa Zimmermann++-- An email address to which users can send suggestions, bug reports, and+-- patches.+maintainer:          brunoczim@gmail.com++-- A copyright notice.+-- copyright:++category:            Data++build-type:          Simple++description:		This package provides JSON data encoding and decoding for Haskell. It also provides option for beautifying the JSON encoding output with indentation and line breaks. The JSValue data type is the center of the package, and it is a type constructor; it may have different Integral types, Fractional Types or IsString types.++-- Extra files to be distributed with the package, such as examples or a+-- README.+extra-source-files:  README.md++-- Constraint on the version of Cabal needed to build this package.+cabal-version:       >=1.10+++library+  -- Modules exported by the library.+  exposed-modules:     Data.Jdh.Json, Data.Jdh.Json.Generic, Data.Jdh.Json.Big++  -- Modules included in this library but not exported.+  -- other-modules:++  -- LANGUAGE extensions used by modules in this package.+  -- other-extensions:++  -- Other library packages from which modules are imported.+  build-depends:       base >=4.8 && <4.9++  -- Directories containing source files.+  hs-source-dirs:      ./++  -- Base language which the package is written in.+  default-language:    Haskell2010
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2017 Bruno Corrêa Zimmermann++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ README.md view
@@ -0,0 +1,18 @@+# JSON-for-Haskell+A JSON implementation for haskell++```haskell+module Main(+    main+) where+import Data.Json+++main :: IO ()+main = do+    print $ fromArray [fromInt 3, fromInt 5, fromStr "Haha"]+    putStrLn $ encode True $ fromProps ["field1" =: fromInt 5, "field2" =: fromReal 3.5]+    putStrLn $ encode False $ fromProps ["condensed JSON data" =: fromBool True]+    print $ decode "{\"hello\": [\"world\"], \"nested\": {\"nested\": true}}"+    return ()+```
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain