json-tools 0.2.4 → 0.3.0
raw patch · 7 files changed
+87/−37 lines, 7 files
Files
- Utils.hs +31/−1
- json-concat.hs +17/−2
- json-deep-select-key.hs +1/−1
- json-iter.hs +18/−29
- json-strings.hs +17/−2
- json-tools.cabal +2/−1
- json-wrap.hs +1/−1
Utils.hs view
@@ -1,7 +1,18 @@-module Utils where+{-# LANGUAGE ScopedTypeVariables #-}+module Utils+ ( readFilesL, readFilesS, decodeFile, parseJSONFiles+ , systemWithStdin)+where +import Text.JSON.AttoJSON+import Data.Functor+import Control.Exception import qualified Data.ByteString as S import qualified Data.ByteString.Lazy as L+import System.IO (hClose)+import System.Exit (ExitCode)+import System.IO.Unsafe (unsafeInterleaveIO)+import qualified System.Process as P readFilesL :: [String] -> IO [L.ByteString] readFilesL args@@ -16,3 +27,22 @@ | otherwise = mapM file args where file "-" = S.getContents file xs = S.readFile xs++decodeFile :: FilePath -> IO (Either String JSValue)+decodeFile fp = parseJSON <$> S.readFile fp++decErr :: String -> a+decErr s = error $ "JSON decoding: " ++ s++parseJSONFiles :: [FilePath] -> IO [JSValue]+parseJSONFiles [] = (:[]) . either decErr id . parseJSON <$> S.getContents+parseJSONFiles xs = mapM (unsafeInterleaveIO . fmap (either decErr id) . decodeFile) xs++systemWithStdin :: String -> S.ByteString -> IO ExitCode+systemWithStdin shellCmd input = do+ (Just stdinHdl, _, _, pHdl) <-+ P.createProcess (P.shell shellCmd){ P.std_in = P.CreatePipe }+ handle (\(_ :: IOException) -> return ()) $ do+ S.hPutStr stdinHdl input+ hClose stdinHdl+ P.waitForProcess pHdl
json-concat.hs view
@@ -1,11 +1,26 @@ import Text.JSON.AttoJSON import qualified Data.ByteString as S+import Control.Monad (when)+import System.IO (hPutStrLn, stderr)+import System.Exit (exitFailure)+import System.Environment (getArgs) +usage :: IO a+usage = mapM_ (hPutStrLn stderr)+ ["Usage: json-concat [--help]"+ ,""+ ,"Reads the standard input as a JSON array of arrays, and writes"+ ,"on standard output the concatenations of these arrays as a JSON array."]+ >> exitFailure+ main :: IO ()-main = S.putStr . showJSON . jsonConcat . either err id . parseJSON =<< S.getContents+main = do args <- getArgs+ when (not . null $ args) usage+ S.putStrLn . showJSON . jsonConcat . either err id . parseJSON+ =<< S.getContents where jsonConcat (JSArray a) = JSArray (concatMap unJSArray a) jsonConcat (JSObject _) = error "unexpected non-JSON array"- jsonConcat _ = error "impossible by decodeStrict post-condition"+ jsonConcat _ = error "not a JSON document (neither array, nor object)" unJSArray (JSArray a) = a unJSArray _ = error "unexpected non-JSON array" err s = error $ "JSON decoding: " ++ s
json-deep-select-key.hs view
@@ -18,5 +18,5 @@ case args of [key] -> S.putStrLn . showJSON . JSArray $ deepSelectKey (S8.pack key) obj- _ -> error "usage: json-deep-select-key <key>"+ _ -> error "Usage: json-deep-select-key <key>"
json-iter.hs view
@@ -1,32 +1,9 @@-{-# LANGUAGE ScopedTypeVariables #-}-import Control.Applicative-import Control.Exception import System.Environment (getArgs)-import System.Exit (ExitCode)-import System.IO (hClose)-import System.IO.Unsafe (unsafeInterleaveIO)-import qualified System.Process as P+import System.IO (hPutStrLn, stderr)+import System.Exit (exitFailure)+import Control.Monad (when) import Text.JSON.AttoJSON-import qualified Data.ByteString as S--err :: String -> a-err s = error $ "JSON decoding: " ++ s--decodeFile :: FilePath -> IO (Either String JSValue)-decodeFile fp = parseJSON <$> S.readFile fp--parseJSONFiles :: [FilePath] -> IO [JSValue]-parseJSONFiles [] = (:[]) . either err id . parseJSON <$> S.getContents-parseJSONFiles xs = mapM (unsafeInterleaveIO . fmap (either err id) . decodeFile) xs--systemWithStdin :: String -> S.ByteString -> IO ExitCode-systemWithStdin shellCmd input = do- (Just stdinHdl, _, _, pHdl) <-- P.createProcess (P.shell shellCmd){ P.std_in = P.CreatePipe }- handle (\(_ :: IOException) -> return ()) $ do- S.hPutStr stdinHdl input- hClose stdinHdl- P.waitForProcess pHdl+import Utils (parseJSONFiles, systemWithStdin) unSequence :: JSValue -> [JSValue] unSequence (JSArray a) = a@@ -37,7 +14,19 @@ mapM_ (mapM_ (systemWithStdin cmd . showJSON) . unSequence) =<< parseJSONFiles jsonfiles +usage :: IO a+usage = mapM_ (hPutStrLn stderr)+ ["Usage: json-iter [--help] <cmd> <json-file>*"+ ,""+ ,"Reads the given JSON files which have to be JSON arrays, and run the given"+ ,"command for each element. The command receive the JSON document as"+ ,"standard input."]+ >> exitFailure+ main :: IO () main = do- cmd:args <- getArgs- iterJSON cmd args+ args <- getArgs+ when ("--help"`elem`args) usage+ case args of+ cmd : files -> iterJSON cmd files+ [] -> usage
json-strings.hs view
@@ -1,7 +1,11 @@ import Text.JSON.AttoJSON import qualified Data.ByteString as S import Data.Monoid-import Data.Foldable+import Data.Foldable hiding (mapM_)+import Control.Monad (when)+import System.IO (hPutStrLn, stderr)+import System.Environment (getArgs)+import System.Exit (exitFailure) -- NOTE that the map keys are not included @@ -14,8 +18,19 @@ go (JSObject m) = foldMap go m go (JSArray xs) = foldMap go xs +usage :: IO a+usage = mapM_ (hPutStrLn stderr)+ ["Usage: json-strings [--help]"+ ,""+ ,"Reads a JSON document as standard input and writes a JSON array"+ ,"of all the strings found in the documents (expect object/mapping keys)."]+ >> exitFailure+ main :: IO ()-main = S.putStr . showJSON -- printing the output+main = do+ args <- getArgs+ when (not . null $ args) usage+ S.putStrLn . showJSON -- printing the output . JSArray . map JSString -- building the result . jsonStrings -- main processing . either err id -- error handling
json-tools.cabal view
@@ -1,6 +1,6 @@ Name: json-tools Cabal-Version: >=1.6-Version: 0.2.4+Version: 0.3.0 License: BSD3 License-File: LICENSE Copyright: (c) Nicolas Pouillard@@ -30,6 +30,7 @@ executable json-iter main-is: json-iter.hs Build-depends: base>=3&&<5, AttoJson, bytestring, process+ Other-modules: Utils ghc-options: -Wall -Odph executable json-lines
json-wrap.hs view
@@ -8,7 +8,7 @@ -- wrap, as in line-wrapping main :: IO ()-main = mapM_ S.putStr . ($[]) . f . either err id . parseJSON =<< S.getContents+main = mapM_ S.putStrLn . ($[]) . f . either err id . parseJSON =<< S.getContents where f (JSArray a) = t"[" . cat (intersperse (t"\n,") (map (t . showJSON) a)) . t"]" f (JSObject o) = t"{" . cat (intersperse (t"\n,") (map g . toList $ o)) . t"}" f _ = error "impossible by decodeStrict post-condition"