Quickson (empty) → 0.1
raw patch · 4 files changed
+108/−0 lines, 4 filesdep +aesondep +attoparsecdep +basesetup-changed
Dependencies added: aeson, attoparsec, base, bytestring, either, text
Files
- LICENSE +30/−0
- Quickson.cabal +24/−0
- Setup.hs +2/−0
- src/Data/Quickson.hs +52/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2011, Scott Sadler.++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++1. Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++2. 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.++3. Neither the name of the author nor the names of his contributors+ may be used to endorse or promote products derived from this software+ without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``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 AUTHORS OR CONTRIBUTORS 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.
+ Quickson.cabal view
@@ -0,0 +1,24 @@+name: quickson+version: 1.0+Build-Type: Simple+cabal-version: >= 1.2+Name: Quickson+Version: 0.1+Cabal-Version: >= 1.2+License: BSD3+License-File: LICENSE+Author: Scott Sadler+Homepage: https://github.com/ssadler/quickson+Category: Text, Web, JSON+Synopsis: Quick JSON extractions with Aeson+++Library+ Exposed-modules: Data.Quickson+ hs-source-dirs: src+ Build-Depends: base >= 3 && < 5,+ bytestring,+ aeson >= 0.7,+ text,+ attoparsec >= 0.12,+ either
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Data/Quickson.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE OverloadedStrings #-}++module Data.Quickson where++import Control.Monad+import Control.Applicative+import Data.Aeson+import qualified Data.Aeson.Types as AT+import Data.Attoparsec.ByteString.Char8 as A8+import qualified Data.ByteString as BS+import qualified Data.ByteString.Char8 as C8+import qualified Data.Text as T+++-- | Quickson intermediary representation+data Quickson = Ob [(T.Text, Bool, Quickson)]+ | Li Quickson+ | Va deriving (Show)+++-- | Parse a quickson structure+quicksonParse :: BS.ByteString -> Either String Quickson+quicksonParse = parseOnly parseStructure+ where+ parseStructure = parseObject <|> parseArray+ parseObject = Ob <$> ("{" *> sepBy1 parseLookups (char ',') <* "}")+ parseArray = Li <$> ("[" *> parseStructure <* "]")+ parseLookups = (,,) <$> (b2t <$> takeWhile1 (notInClass "?,:}"))+ <*> ("?" *> pure True <|> pure False)+ <*> (":" *> parseStructure <|> pure Va)+ b2t = T.pack . C8.unpack+++-- | Execute a quickson structure against a value+quicksonExecute :: FromJSON a => Quickson -> Value -> Either String a+quicksonExecute que = AT.parseEither (drill que >=> parseJSON)+ where+ drill :: Quickson -> Value -> AT.Parser Value+ drill (Ob [l]) = parseJSON >=> flip look l+ drill (Ob keys) = parseJSON >=> forM keys . look >=> return . toJSON+ drill (Li q) = parseJSON >=> mapM (drill q) >=> return . toJSON+ drill Va = return+ look v (k,True,qq) = v.:?k >>= maybe (return Null) (drill qq)+ look v (k,False,qq) = v.:k >>= drill qq+++-- | Perform a JSON extraction+quickson :: FromJSON a => BS.ByteString -> BS.ByteString -> Either String a+quickson structureSpec bs = do+ val <- eitherDecodeStrict bs+ query <- quicksonParse structureSpec+ quicksonExecute query val