jsonl (empty) → 0.1.0.0
raw patch · 5 files changed
+162/−0 lines, 5 filesdep +aesondep +basedep +bytestringsetup-changed
Dependencies added: aeson, base, bytestring
Files
- LICENSE +30/−0
- README.md +3/−0
- Setup.hs +2/−0
- jsonl.cabal +47/−0
- src/JSONL.hs +80/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Author name here (c) 2022++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * 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.++ * Neither the name of Author name here nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 COPYRIGHT+OWNER 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.
+ README.md view
@@ -0,0 +1,3 @@+# jsonl++Adapter between 'aeson' and the JSONL format (https://jsonlines.org/)
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ jsonl.cabal view
@@ -0,0 +1,47 @@+name: jsonl+version: 0.1.0.0+synopsis: JSON Lines+description: Parse and serialize the JSONL format via @aeson@'s ToJSON/FromJSON+homepage: https://github.com/unfoldml/jsonl+license: BSD3+license-file: LICENSE+author: Marco Zocca+maintainer: UnfoldML AB+copyright: (c) 2022 UnfoldML AB, Marco Zocca+category: JSON, Web, Text+build-type: Simple+extra-source-files: README.md+cabal-version: >=1.10+tested-with: GHC == 7.10.2++library+ default-language: Haskell2010+ ghc-options: -Wall+ hs-source-dirs: src+ exposed-modules: JSONL+ build-depends: base >= 4.7 && < 5+ , aeson+ , bytestring++-- executable jsonl+-- default-language: Haskell2010+-- ghc-options: -threaded -rtsopts -with-rtsopts=-N+-- hs-source-dirs: app+-- main-is: Main.hs+-- build-depends: base+-- , jsonl++-- test-suite spec+-- default-language: Haskell2010+-- ghc-options: -Wall+-- type: exitcode-stdio-1.0+-- hs-source-dirs: test+-- main-is: Spec.hs+-- build-depends: base+-- , jsonl+-- , hspec+-- , QuickCheck++source-repository head+ type: git+ location: https://github.com/unfoldml/jsonl
+ src/JSONL.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE RankNTypes #-}+{-# language DeriveGeneric #-}+{-# language OverloadedStrings #-}+-- | JSON Lines https://jsonlines.org/+module JSONL (+ -- * Encode+ jsonlWriteFile, jsonlToLBS, jsonlBuilder+ -- * Decode+ , jsonlFromLBS+ ) where++import System.IO (Handle, IOMode(..), withBinaryFile)++-- aeson+import Data.Aeson (ToJSON(..), FromJSON(..), encode, eitherDecode' )+-- bytestring+import qualified Data.ByteString.Builder as BBS (toLazyByteString, Builder, lazyByteString, string7)+import qualified Data.ByteString.Builder.Internal as BBS (hPut, putBuilder)+import qualified Data.ByteString.Internal as BS (c2w)+import qualified Data.ByteString.Lazy as LBS (ByteString, span)++import Prelude hiding (writeFile)++-- | Parse a JSONL-encoded collection of objects from a `LBS.ByteString`+--+-- If parsing fails, returns the first parsing error in a Left+jsonlFromLBS :: FromJSON a => LBS.ByteString -> Either String [a]+jsonlFromLBS = sequence . jsonlFromLBS_++jsonlFromLBS_ :: FromJSON a => LBS.ByteString -> [Either String a]+jsonlFromLBS_ = go mempty+ where+ go :: FromJSON a => [Either String a] -> LBS.ByteString -> [Either String a]+ go acc lbs = let+ (s, srest) = LBS.span (== BS.c2w '\n') lbs+ in go (eitherDecode' s : acc) srest+++-- jsonlFromLBS' :: FromJSON a => LBS.ByteString -> Either String [a]+-- jsonlFromLBS' = chop1 (Right mempty)++-- chop1 :: FromJSON a =>+-- Either String [a] -> LBS.ByteString -> Either String [a]+-- chop1 acce lbs = case acce of+-- Right acc -> case eitherDecode' s of+-- Right x -> chop1 (Right (x : acc)) srest+-- Left e -> Left e+-- ex -> ex+-- where+-- (s, srest) = LBS.span (== BS.c2w '\n') lbs++-- | Write a collection of objects to a JSONL-encoded file+jsonlWriteFile :: (Foldable t, ToJSON a) => FilePath -> t a -> IO ()+jsonlWriteFile fpath xs = writeFile fpath (jsonlBuilder xs)++-- | Render a collection of objects to a JSONL-encoded `LBS.ByteString`+jsonlToLBS :: (Foldable t, ToJSON a) => t a -> LBS.ByteString+jsonlToLBS xs = BBS.toLazyByteString $ jsonlBuilder xs ++jsonlBuilder :: (Foldable t, ToJSON a) => t a -> BBS.Builder+jsonlBuilder = foldMap jsonLine++jsonLine :: ToJSON a => a -> BBS.Builder+jsonLine x = jsonToBuilder x <> BBS.string7 "\n"++jsonToBuilder :: ToJSON a => a -> BBS.Builder+jsonToBuilder = BBS.lazyByteString . encode+++-- vendored from bytestring < 0.11.2++hPutBuilder :: Handle -> BBS.Builder -> IO ()+hPutBuilder h = BBS.hPut h . BBS.putBuilder++modifyFile :: IOMode -> FilePath -> BBS.Builder -> IO ()+modifyFile mode f bld = withBinaryFile f mode (`hPutBuilder` bld)++writeFile :: FilePath -> BBS.Builder -> IO ()+writeFile = modifyFile WriteMode+