packages feed

jsontsv 0.1.5.0 → 0.1.6.0

raw patch · 4 files changed

+66/−10 lines, 4 filesdep ~base

Dependency ranges changed: base

Files

Main.hs view
@@ -9,10 +9,10 @@ import qualified Data.List  import qualified Data.Text as T import qualified Data.Text.Lazy.IO as TL-import Data.Maybe (catMaybes)+import Data.Maybe (catMaybes, listToMaybe) import Control.Applicative import Control.Monad (when)-import Data.ByteString.Lazy as BL hiding (map, intersperse)+import qualified Data.ByteString.Lazy as BL hiding (map, intersperse) import qualified Data.ByteString.Lazy.Char8 as BS import Data.Attoparsec.Lazy as Atto hiding (Result) import Data.Attoparsec.ByteString.Char8 (endOfLine, sepBy)@@ -130,8 +130,20 @@ -- | KeyPath may have an alias for the header output data KeyPath = KeyPath [Key] (Maybe Text) deriving Show -data Key = Key Text | Index Int deriving (Eq, Show)+{-+  Key represents an object (HashMap) key.+  Index represents a position in an Array+  TupleKey represents a Text key in an array of pairs that should be treated +    as a map. E.g.+        [["dinner","fish"],["dessert","pie"]]+    This is useful in the case of Data.Aeson emits pair tuples:+        [("dinner", "fish"),("dessert","pie")]+-}+data Key = Key Text +         | Index Int +         | TupleKey Text deriving (Eq, Show) + parseKeyPath :: Text -> [KeyPath] parseKeyPath s = case AT.parseOnly pKeyPaths s of     Left err -> error $ "Parse error " ++ err @@ -154,12 +166,21 @@     Just <$> AT.takeWhile1 (AT.inClass "a-zA-Z0-9_-")  pKeyOrIndex :: AT.Parser Key-pKeyOrIndex = pIndex <|> pKey+pKeyOrIndex = pTupleKey <|> pIndex <|> pKey -pKey = Key <$> AT.takeWhile1 (AT.notInClass " .[:")+pIndex :: AT.Parser Key   +pIndex = Index <$> AT.decimal  -pIndex = Index <$> AT.decimal <* AT.char ']'+pTupleKey :: AT.Parser Key+pTupleKey = do +    AT.char '"' +    xs <- AT.takeWhile1 (AT.notInClass "\"")+    AT.char '"'+    return $ TupleKey xs +pKey :: AT.Parser Key+pKey = Key <$> AT.takeWhile1 (AT.notInClass " .[:")+ evalToLineBuilder :: Config -> String -> [[Key]] -> Value -> B.Builder  evalToLineBuilder config@Config{..} outDelim ks v =      mconcat $ intersperse (B.fromText . T.pack $ outDelim) $  map (flip (evalToBuilder config) v) ks@@ -196,13 +217,18 @@       in case e of          Just e' -> evalKeyPath config ks e'         Nothing -> Null+evalKeyPath config (TupleKey k:ks) (Array v) = +      -- array must be an array of 2-tuples+      let vs :: [(Value, Value)]+          vs = [(V.head tuple, tuple V.! 1) | Array tuple <- V.toList v , V.length tuple == 2]+          e = listToMaybe [v' | (String k', v') <- vs, k' == k]+      in maybe Null (evalKeyPath config ks) e -- traverse array elements with additional keys -- if key is _, e.g. cast._[0] , traverse INTO each array object -- e.g. "cast":[["Michael Caine",13473],["Demi Moore",65231],... evalKeyPath config@Config{..} (Key "_":ks) (Array v) =        String . mconcat . intersperse arrayDelim $ map (evalToText config ks) (V.toList v) -- traverse array elements with additional keys- evalKeyPath _ ks@(Key key:_) (Array v) | V.null v = Null evalKeyPath config@Config{..} ks@(Key key:_) (Array v) =        let vs = V.toList v
README.md view
@@ -86,12 +86,36 @@  with this expression -    jsontsv -a '|' 'cast._[0]'+    jsontsv -a '|' 'id cast._[0]' < input  This results in:          2   Michael Caine|Demi Moore +## Extracting 2-tuple values++From version 0.1.5.0, you can can access lists of pairs, e.g.++    {"menu":[["dinner","fish"],["dessert","pie"]]}++with the expression `["KEY"]`, e.g.:++    jsontsv 'menu["dinner"]'+    # => fish++    jsontsv 'menu["dessert"]'+    # => pie++    jsontsv 'menu["drink"]'+    # => null++This is useful because Data.Aeson emits Haskell 2-tuples in this format:++    ghci> encode [("dinner", "fish"),("dessert","pie")]+    "[[\"dinner\",\"fish\"],[\"dessert\",\"pie\"]]"++Moreover, encoding 2-tuples is often preferable to encoding `Data.Map.Map` because +encoding 2-tuples preserves ordering, whereas encoding `Map` does not.  ## Installation 
jsontsv.cabal view
@@ -2,7 +2,7 @@ --  see http://haskell.org/cabal/users-guide/  name:                jsontsv-version:             0.1.5.0+version:             0.1.6.0 synopsis:            JSON to TSV transformer homepage:            https://github.com/danchoi/jsontsv description:         Transforms JSON into tab-separated line-oriented output, for easier processing in Unix-style pipelines.@@ -17,7 +17,7 @@  executable jsontsv   main-is:             Main.hs-  build-depends:       base >=4.6 && <4.8+  build-depends:       base >=4.6 && <4.9                      , aeson >= 0.8.0.0                      , bytestring                      , attoparsec >= 0.12.0.0
+ stack.yaml view
@@ -0,0 +1,6 @@+flags: {}+packages:+- '.'+extra-deps: +- string-qq-0.0.2+resolver: lts-3.0