packages feed

aeson-qq (empty) → 0.4.0

raw patch · 4 files changed

+165/−0 lines, 4 filesdep +aesondep +basedep +haskell-src-metasetup-changed

Dependencies added: aeson, base, haskell-src-meta, json-qq, parsec, template-haskell

Files

+ COPYING.txt view
@@ -0,0 +1,14 @@+            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE+                    Version 2, December 2004++ Copyright (C) 2010 Oscar Finnsson++ Everyone is permitted to copy and distribute verbatim or modified+ copies of this license document, and changing it is allowed as long+ as the name is changed.++            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION++  0. You just DO WHAT THE FUCK YOU WANT TO.+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ aeson-qq.cabal view
@@ -0,0 +1,34 @@+name:                aeson-qq+version:             0.4.0+synopsis:            Json Quasiquatation for Haskell.++-- A longer description of the package.+description:  +    @aeson-qq@ provides json quasiquatation for Haskell.+    .+    This package expose the function @aesonQQ@ that compile time converts json code into a @Data.Aeson.Value@.+    @aesonQQ@ got the signature+    .+    > aesonQQ :: QuasiQuoter.+    .+    Consult documentation in the module @Data.Aeson.QQ@.++homepage:            http://github.com/finnsson/aeson-qq+license:             OtherLicense+license-file:        COPYING.txt+author:              Oscar Finnsson+maintainer:          oscar.finnsson@gmail.com+category:            JSON+build-type:          Simple+cabal-version:       >=1.6++library+  hs-source-dirs: src+  exposed-modules: Data.Aeson.QQ+  build-depends: base >= 4.3 && < 5, aeson, parsec >= 2 && < 3, json-qq, template-haskell, haskell-src-meta >= 0.1.0++source-repository head+  type:     git+  location: https://github.com/finnsson/aeson-qq/++
+ src/Data/Aeson/QQ.hs view
@@ -0,0 +1,115 @@+{-# OPTIONS_GHC -XTemplateHaskell -XQuasiQuotes -XUndecidableInstances #-}++-- | This package expose the function @aesonQQ@ that compile time converts json code into a @Data.Aeson.Value@.+--    @aesonQQ@ got the signature+--    +--    > aesonQQ :: QuasiQuoter+--    +--    and is used like+--    +--    > myCode = [aesonQQ| {age: 23, name: "Pelle", likes: ["mac","Haskell"] } |]+--    +--    where it is important that+--    +--    * you got no space in @[aesonQQ|@ and+--    +--    * no additional code after @|]@.+--    +--    The quasiquatation can also bind to variables like+--    +--    > myCode = [aesonQQ| {age: <|age|>, name: <|name|>} |]+--    > where age = 34 :: Integer+--    >       name = "Pelle"+--    +--    where the function  @toJSON@ will be called on @age@ and @name@ runtime.+--+--    You can also insert Haskell code: +--+--    > myCode = [aesonQQ| {age: <|age + 34 :: Integer|>, name: <|map toUpper name|>} |]+--    > where age = 34 :: Integer+--    >       name = "Pelle"+--    +--    You can use a similar syntax if you want to insert a value of type Data.Aeson.Value like+--    +--    > myCode = [aesonQQ| {"age": <<age>>} |]+--    +--    If you want to replace the name of the key in a hash you'll use the $-syntax:+--    +--    > foo = [aesonQQ| {$bar: 42} |]+--    > bar = "age"+--    ++module Data.Aeson.QQ (+  aesonQQ+) where++import Language.Haskell.TH+import Language.Haskell.TH.Quote++import Data.Data+import Data.Maybe++import Data.JSON.QQ as QQ++import Data.Aeson as A+import Data.Aeson.Generic++import Data.Ratio+import Text.ParserCombinators.Parsec+import Text.ParserCombinators.Parsec.Error++import Language.Haskell.Meta.Parse++aesonQQ :: QuasiQuoter+aesonQQ = QuasiQuoter { +  quoteExp = jsonExp, +  quotePat = \s -> error "No quotePat defined for jsonQQ",+  quoteType = \s -> error "No quoteType defined for jsonQQ",+  quoteDec = \s -> error "No quoteDec defined for jsonQQ"+}+++jsonExp :: String -> ExpQ+jsonExp txt =+  case parsed' of +    Left err -> error $ "Error in aesonExp: " ++ show err+    Right val -> return $ toExp val+  where+    parsed' = QQ.parsedJson txt++----+-- JSValue etc to ExpQ+---------+toExp :: QQ.JsonValue -> Exp++toExp (JsonString str) = +    AppE (ConE $ mkName "Data.Aeson.Types.String") (packE (LitE (StringL $ str)))++toExp (JsonNull) = ConE $ mkName "Data.Aeson.Types.Null"++toExp (JsonObject objs) = +    (AppE (VarE $ mkName "Data.Aeson.Types.object") (ListE $ jsList ))+    where+      jsList :: [Exp] -- [(String,JSValue)]+      jsList = map objs2list (objs)+      objs2list :: (HashKey,JsonValue) -> Exp+      objs2list (HashStringKey k,v) = TupE [packE (LitE (StringL k)), toExp v]+      objs2list (HashVarKey k,v) = TupE [packE (VarE $ mkName k), toExp v]++toExp (JsonArray arr) =+    AppE (ConE $ mkName "Data.Aeson.Types.Array") (AppE (VarE $ mkName "Data.Vector.fromList") (ListE $ map toExp arr))++toExp (JsonNumber b rat) =+    AppE (ConE $ mkName "Data.Aeson.Types.Number") (AppE (ConE $ mkName "Data.Attoparsec.Number.D") (LitE (RationalL rat)))   +toExp (JsonIdVar v) =+    VarE $ mkName v++toExp (JsonBool b) =+    AppE (ConE $ mkName "Data.Aeson.Types.Bool") (ConE $ mkName (if b then "True" else "False"))++toExp (JsonCode exp) =+    AppE (VarE $ mkName "Data.Aeson.Generic.toJSON") exp++-- Helpers+packE = AppE (VarE $ mkName "Data.Text.pack")+