packages feed

json-bytes-builder 0.3 → 0.4

raw patch · 16 files changed

+353/−348 lines, 16 files

Files

demo/Main.hs view
@@ -4,7 +4,7 @@ import Data.ByteString (ByteString) import Data.Text (Text) import qualified JSONBytesBuilder.Builder as A-import qualified JSONBytesBuilder.Interpreters.ByteString as B+import qualified JSONBytesBuilder.ByteString.ByteString as B import qualified Data.ByteString.Char8 as C  
json-bytes-builder.cabal view
@@ -1,7 +1,7 @@ name:   json-bytes-builder version:-  0.3+  0.4 synopsis:   Direct-to-bytes JSON Builder description:@@ -47,14 +47,15 @@   default-language:     Haskell2010   other-modules:-    JSONBytesBuilder.Prelude-    JSONBytesBuilder.ByteString.BoundedPrims-    JSONBytesBuilder.ByteString.Builders+    JSONBytesBuilder.Private.Prelude+    JSONBytesBuilder.Private.ByteString.BoundedPrim+    JSONBytesBuilder.Private.ByteString.Builder+    JSONBytesBuilder.Private.Builder   exposed-modules:     JSONBytesBuilder.Builder-    JSONBytesBuilder.Interpreters.ByteStringBuilder-    JSONBytesBuilder.Interpreters.ByteString-    JSONBytesBuilder.Interpreters.LazyByteString+    JSONBytesBuilder.ByteString.Builder+    JSONBytesBuilder.ByteString.ByteString+    JSONBytesBuilder.ByteString.LazyByteString   build-depends:     scientific == 0.3.*,     text == 1.*,
library/JSONBytesBuilder/Builder.hs view
@@ -22,140 +22,4 @@ ) where -import JSONBytesBuilder.Prelude hiding (null)-import qualified Data.ByteString.Builder as A-import qualified JSONBytesBuilder.ByteString.Builders as E----- |--- Builder of any JSON literal.-newtype Literal =-  Literal A.Builder---- |--- Builder of JSON Object rows.-newtype Rows =-  Rows (Maybe A.Builder)--instance Monoid Rows where-  {-# INLINE mempty #-}-  mempty =-    Rows Nothing-  {-# INLINE mappend #-}-  mappend =-    \case-      Rows (Just left) ->-        \case-          Rows (Just right) ->-            Rows (Just (left <> A.char8 ',' <> right))-          _ ->-            Rows (Just left)-      Rows Nothing ->-        id---- |--- Builder of JSON Array elements.-newtype Elements =-  Elements (Maybe A.Builder)--instance Monoid Elements where-  {-# INLINE mempty #-}-  mempty =-    Elements Nothing-  {-# INLINE mappend #-}-  mappend =-    \case-      Elements (Just left) ->-        \case-          Elements (Just right) ->-            Elements (Just (left <> A.char8 ',' <> right))-          _ ->-            Elements (Just left)-      Elements Nothing ->-        id---- |--- JSON Null literal.-{-# INLINE null #-}-null :: Literal-null =-  Literal (inline E.null)---- |--- JSON Boolean literal from 'Bool'.-{-# INLINE boolean #-}-boolean :: Bool -> Literal-boolean =-  Literal . inline E.boolean---- |--- JSON Number literal from 'Int'.-{-# INLINE number_int #-}-number_int :: Int -> Literal-number_int =-  Literal . inline A.intDec---- |--- JSON Number literal from 'Integer'.-{-# INLINE number_integer #-}-number_integer :: Integer -> Literal-number_integer =-  Literal . inline A.integerDec---- |--- JSON Number literal from 'Double'.-{-# INLINE number_double #-}-number_double :: Double -> Literal-number_double =-  Literal . inline A.doubleDec---- |--- JSON Number literal from 'Scientific'.-{-# INLINE number_scientific #-}-number_scientific :: Scientific -> Literal-number_scientific =-  Literal . inline E.scientific---- |--- JSON String literal from 'Text'.-{-# INLINE string #-}-string :: Text -> Literal-string =-  Literal . inline E.string---- |--- JSON Object literal from the 'Rows' builder.-{-# INLINE object #-}-object :: Rows -> Literal-object (Rows x) =-  Literal (maybe E.emptyObject (inline E.inCurlies) x)---- |--- JSON Array literal from the 'Elements' builder.-{-# INLINE array #-}-array :: Elements -> Literal-array (Elements x) =-  Literal (maybe E.emptyArray (inline E.inSquarelies) x)---- |--- Rows builder from a key-value pair,--- where value is an already encoded JSON literal.--- --- Use the 'Rows' 'Monoid' instance--- to construct multi-row objects.-{-# INLINE row #-}-row :: Text -> Literal -> Rows-row key (Literal literal) =-  Rows (Just (inline E.row key literal))---- |--- Elements builder from an element,--- which is an already encoded JSON literal.--- --- Use the 'Elements' 'Monoid' instance--- to construct multi-element arrays.-{-# INLINE element #-}-element :: Literal -> Elements-element (Literal literal) =-  Elements (Just literal)-+import JSONBytesBuilder.Private.Builder
− library/JSONBytesBuilder/ByteString/BoundedPrims.hs
@@ -1,72 +0,0 @@-module JSONBytesBuilder.ByteString.BoundedPrims-where--import JSONBytesBuilder.Prelude-import Data.ByteString.Builder.Prim---{-# INLINE null #-}-null :: BoundedPrim ()-null =-  ascii4 ('n', ('u', ('l', 'l')))--{-# INLINE boolean #-}-boolean :: BoundedPrim Bool-boolean =-  condB id (ascii4 ('t', ('r', ('u', 'e')))) (ascii5 ('f', ('a', ('l', ('s', 'e')))))--{-# INLINE emptyArray #-}-emptyArray :: BoundedPrim ()-emptyArray =-  ascii2 ('[', ']')--{-# INLINE emptyObject #-}-emptyObject :: BoundedPrim ()-emptyObject =-  ascii2 ('{', '}')--{-# INLINE stringEncodedByte #-}-stringEncodedByte :: BoundedPrim Word8-stringEncodedByte =-  condB (== (fromIntegral . ord) '\\') (ascii2 ('\\', '\\')) $-  condB (== (fromIntegral . ord) '\"') (ascii2 ('\\', '"')) $-  condB (>= (fromIntegral . ord) '\x20') (liftFixedToBounded word8) $-  condB (== (fromIntegral . ord) '\n') (ascii2 ('\\', 'n')) $-  condB (== (fromIntegral . ord) '\r') (ascii2 ('\\', 'r')) $-  condB (== (fromIntegral . ord) '\t') (ascii2 ('\\', 't')) $-  hexEncodedByte--{-# INLINE hexEncodedByte #-}-hexEncodedByte :: BoundedPrim Word8-hexEncodedByte =-  liftFixedToBounded ((\c -> ('\\', ('u', fromIntegral c))) >$< char8 >*< char8 >*< word16HexFixed)--{-# INLINE ascii2 #-}-ascii2 :: (Char, Char) -> BoundedPrim a-ascii2 cs =-  liftFixedToBounded $-  const cs >$< char8 >*< char8--{-# INLINE ascii4 #-}-ascii4 :: (Char, (Char, (Char, Char))) -> BoundedPrim a-ascii4 cs =-  liftFixedToBounded $-  const cs >$< char8 >*< char8 >*< char8 >*< char8--{-# INLINE ascii5 #-}-ascii5 :: (Char, (Char, (Char, (Char, Char)))) -> BoundedPrim a-ascii5 cs =-  liftFixedToBounded $-  const cs >$< char8 >*< char8 >*< char8 >*< char8 >*< char8--{-# INLINE ascii6 #-}-ascii6 :: (Char, (Char, (Char, (Char, (Char, Char))))) -> BoundedPrim a-ascii6 cs =-  liftFixedToBounded $ -  const cs >$< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8--{-# INLINE ascii8 #-}-ascii8 :: (Char, (Char, (Char, (Char, (Char, (Char, (Char, Char))))))) -> BoundedPrim a-ascii8 cs =-  liftFixedToBounded $-  const cs >$< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8
+ library/JSONBytesBuilder/ByteString/Builder.hs view
@@ -0,0 +1,17 @@+module JSONBytesBuilder.ByteString.Builder+(+  jsonLiteral,+)+where++import JSONBytesBuilder.Private.Prelude hiding (length, null)+import JSONBytesBuilder.Private.Builder+import Data.ByteString.Builder+++-- |+-- Produce a JSON ByteString builder with compact syntax from a literal builder.+{-# INLINE jsonLiteral #-}+jsonLiteral :: Literal -> Builder+jsonLiteral (Literal builder) =+  builder
− library/JSONBytesBuilder/ByteString/Builders.hs
@@ -1,66 +0,0 @@-module JSONBytesBuilder.ByteString.Builders-where--import JSONBytesBuilder.Prelude hiding (length, null)-import Data.ByteString.Builder-import qualified JSONBytesBuilder.ByteString.BoundedPrims as A-import qualified Data.ByteString.Builder.Prim as A-import qualified Data.Text.Encoding as B-import qualified Data.Scientific as C-import qualified Data.ByteString.Builder.Scientific as D---{-# INLINABLE null #-}-null :: Builder-null =-  A.primBounded A.null ()--{-# INLINABLE boolean #-}-boolean :: Bool -> Builder-boolean =-  A.primBounded A.boolean--{-# INLINABLE string #-}-string :: Text -> Builder-string x =-  char8 '"' <> B.encodeUtf8BuilderEscaped A.stringEncodedByte x <> char8 '"'--{-# INLINABLE scientific #-}-scientific :: Scientific -> Builder-scientific n =-  if e < 0-    then D.scientificBuilder n-    else integerDec (C.coefficient n * 10 ^ e)-  where-    e =-      C.base10Exponent n--{-# INLINABLE inCurlies #-}-inCurlies :: Builder -> Builder-inCurlies x =-  char8 '{' <> x <> char8 '}'--{-# INLINABLE row #-}-row :: Text -> Builder -> Builder-row key value =-  string key <> char8 ':' <> value--{-# INLINABLE inSquarelies #-}-inSquarelies :: Builder -> Builder-inSquarelies x =-  char8 '[' <> x <> char8 ']'--{-# INLINABLE commaSeparated #-}-commaSeparated :: Builder -> Builder -> Builder-commaSeparated left right =-  left <> char8 ',' <> right--{-# INLINABLE emptyObject #-}-emptyObject :: Builder-emptyObject =-  A.primBounded A.emptyObject ()--{-# INLINABLE emptyArray #-}-emptyArray :: Builder-emptyArray =-  A.primBounded A.emptyArray ()
+ library/JSONBytesBuilder/ByteString/ByteString.hs view
@@ -0,0 +1,18 @@+module JSONBytesBuilder.ByteString.ByteString+(+  jsonLiteral,+)+where++import JSONBytesBuilder.Private.Prelude hiding (length, null)+import JSONBytesBuilder.Builder+import qualified JSONBytesBuilder.ByteString.LazyByteString as A+import qualified Data.ByteString.Lazy as B+++-- |+-- Produce a strict JSON ByteString with compact syntax from a literal builder.+{-# INLINE jsonLiteral #-}+jsonLiteral :: Literal -> ByteString+jsonLiteral =+  B.toStrict . A.jsonLiteral
+ library/JSONBytesBuilder/ByteString/LazyByteString.hs view
@@ -0,0 +1,19 @@+module JSONBytesBuilder.ByteString.LazyByteString+(+  jsonLiteral,+)+where++import JSONBytesBuilder.Private.Prelude hiding (length, null)+import JSONBytesBuilder.Builder+import Data.ByteString.Builder+import qualified JSONBytesBuilder.ByteString.Builder as A+import qualified Data.ByteString.Lazy as B+++-- |+-- Produce a lazy JSON ByteString with compact syntax from a literal builder.+{-# INLINE jsonLiteral #-}+jsonLiteral :: Literal -> B.ByteString+jsonLiteral =+  toLazyByteString . A.jsonLiteral
− library/JSONBytesBuilder/Interpreters/ByteString.hs
@@ -1,18 +0,0 @@-module JSONBytesBuilder.Interpreters.ByteString-(-  jsonLiteral,-)-where--import JSONBytesBuilder.Prelude hiding (length, null)-import JSONBytesBuilder.Builder-import qualified JSONBytesBuilder.Interpreters.LazyByteString as A-import qualified Data.ByteString.Lazy as B----- |--- Produce a strict JSON ByteString with compact syntax from a literal builder.-{-# INLINE jsonLiteral #-}-jsonLiteral :: Literal -> ByteString-jsonLiteral =-  B.toStrict . A.jsonLiteral
− library/JSONBytesBuilder/Interpreters/ByteStringBuilder.hs
@@ -1,17 +0,0 @@-module JSONBytesBuilder.Interpreters.ByteStringBuilder-(-  jsonLiteral,-)-where--import JSONBytesBuilder.Prelude hiding (length, null)-import JSONBytesBuilder.Builder-import Data.ByteString.Builder----- |--- Produce a JSON ByteString builder with compact syntax from a literal builder.-{-# INLINE jsonLiteral #-}-jsonLiteral :: Literal -> Builder-jsonLiteral =-  unsafeCoerce
− library/JSONBytesBuilder/Interpreters/LazyByteString.hs
@@ -1,19 +0,0 @@-module JSONBytesBuilder.Interpreters.LazyByteString-(-  jsonLiteral,-)-where--import JSONBytesBuilder.Prelude hiding (length, null)-import JSONBytesBuilder.Builder-import Data.ByteString.Builder-import qualified JSONBytesBuilder.Interpreters.ByteStringBuilder as A-import qualified Data.ByteString.Lazy as B----- |--- Produce a lazy JSON ByteString with compact syntax from a literal builder.-{-# INLINE jsonLiteral #-}-jsonLiteral :: Literal -> B.ByteString-jsonLiteral =-  toLazyByteString . A.jsonLiteral
− library/JSONBytesBuilder/Prelude.hs
@@ -1,11 +0,0 @@-module JSONBytesBuilder.Prelude-(-  module Exports,-)-where--import BasePrelude as Exports hiding ((<>))-import Data.Semigroup as Exports (Semigroup(..))-import Data.Text as Exports (Text)-import Data.ByteString as Exports (ByteString)-import Data.Scientific as Exports (Scientific)
+ library/JSONBytesBuilder/Private/Builder.hs view
@@ -0,0 +1,140 @@+module JSONBytesBuilder.Private.Builder+where++import JSONBytesBuilder.Private.Prelude hiding (null)+import qualified Data.ByteString.Builder as A+import qualified JSONBytesBuilder.Private.ByteString.Builder as E+++-- |+-- Builder of any JSON literal.+newtype Literal =+  Literal A.Builder++-- |+-- Builder of JSON Object rows.+newtype Rows =+  Rows (Maybe A.Builder)++instance Monoid Rows where+  {-# INLINE mempty #-}+  mempty =+    Rows Nothing+  {-# INLINE mappend #-}+  mappend =+    \case+      Rows (Just left) ->+        \case+          Rows (Just right) ->+            Rows (Just (left <> A.char8 ',' <> right))+          _ ->+            Rows (Just left)+      Rows Nothing ->+        id++-- |+-- Builder of JSON Array elements.+newtype Elements =+  Elements (Maybe A.Builder)++instance Monoid Elements where+  {-# INLINE mempty #-}+  mempty =+    Elements Nothing+  {-# INLINE mappend #-}+  mappend =+    \case+      Elements (Just left) ->+        \case+          Elements (Just right) ->+            Elements (Just (left <> A.char8 ',' <> right))+          _ ->+            Elements (Just left)+      Elements Nothing ->+        id++-- |+-- JSON Null literal.+{-# INLINE null #-}+null :: Literal+null =+  Literal (inline E.null)++-- |+-- JSON Boolean literal from 'Bool'.+{-# INLINE boolean #-}+boolean :: Bool -> Literal+boolean =+  Literal . inline E.boolean++-- |+-- JSON Number literal from 'Int'.+{-# INLINE number_int #-}+number_int :: Int -> Literal+number_int =+  Literal . inline A.intDec++-- |+-- JSON Number literal from 'Integer'.+{-# INLINE number_integer #-}+number_integer :: Integer -> Literal+number_integer =+  Literal . inline A.integerDec++-- |+-- JSON Number literal from 'Double'.+{-# INLINE number_double #-}+number_double :: Double -> Literal+number_double =+  Literal . inline A.doubleDec++-- |+-- JSON Number literal from 'Scientific'.+{-# INLINE number_scientific #-}+number_scientific :: Scientific -> Literal+number_scientific =+  Literal . inline E.scientific++-- |+-- JSON String literal from 'Text'.+{-# INLINE string #-}+string :: Text -> Literal+string =+  Literal . inline E.string++-- |+-- JSON Object literal from the 'Rows' builder.+{-# INLINE object #-}+object :: Rows -> Literal+object (Rows x) =+  Literal (maybe E.emptyObject (inline E.inCurlies) x)++-- |+-- JSON Array literal from the 'Elements' builder.+{-# INLINE array #-}+array :: Elements -> Literal+array (Elements x) =+  Literal (maybe E.emptyArray (inline E.inSquarelies) x)++-- |+-- Rows builder from a key-value pair,+-- where value is an already encoded JSON literal.+-- +-- Use the 'Rows' 'Monoid' instance+-- to construct multi-row objects.+{-# INLINE row #-}+row :: Text -> Literal -> Rows+row key (Literal literal) =+  Rows (Just (inline E.row key literal))++-- |+-- Elements builder from an element,+-- which is an already encoded JSON literal.+-- +-- Use the 'Elements' 'Monoid' instance+-- to construct multi-element arrays.+{-# INLINE element #-}+element :: Literal -> Elements+element (Literal literal) =+  Elements (Just literal)+
+ library/JSONBytesBuilder/Private/ByteString/BoundedPrim.hs view
@@ -0,0 +1,72 @@+module JSONBytesBuilder.Private.ByteString.BoundedPrim+where++import JSONBytesBuilder.Private.Prelude+import Data.ByteString.Builder.Prim+++{-# INLINE null #-}+null :: BoundedPrim ()+null =+  ascii4 ('n', ('u', ('l', 'l')))++{-# INLINE boolean #-}+boolean :: BoundedPrim Bool+boolean =+  condB id (ascii4 ('t', ('r', ('u', 'e')))) (ascii5 ('f', ('a', ('l', ('s', 'e')))))++{-# INLINE emptyArray #-}+emptyArray :: BoundedPrim ()+emptyArray =+  ascii2 ('[', ']')++{-# INLINE emptyObject #-}+emptyObject :: BoundedPrim ()+emptyObject =+  ascii2 ('{', '}')++{-# INLINE stringEncodedByte #-}+stringEncodedByte :: BoundedPrim Word8+stringEncodedByte =+  condB (== (fromIntegral . ord) '\\') (ascii2 ('\\', '\\')) $+  condB (== (fromIntegral . ord) '\"') (ascii2 ('\\', '"')) $+  condB (>= (fromIntegral . ord) '\x20') (liftFixedToBounded word8) $+  condB (== (fromIntegral . ord) '\n') (ascii2 ('\\', 'n')) $+  condB (== (fromIntegral . ord) '\r') (ascii2 ('\\', 'r')) $+  condB (== (fromIntegral . ord) '\t') (ascii2 ('\\', 't')) $+  hexEncodedByte++{-# INLINE hexEncodedByte #-}+hexEncodedByte :: BoundedPrim Word8+hexEncodedByte =+  liftFixedToBounded ((\c -> ('\\', ('u', fromIntegral c))) >$< char8 >*< char8 >*< word16HexFixed)++{-# INLINE ascii2 #-}+ascii2 :: (Char, Char) -> BoundedPrim a+ascii2 cs =+  liftFixedToBounded $+  const cs >$< char8 >*< char8++{-# INLINE ascii4 #-}+ascii4 :: (Char, (Char, (Char, Char))) -> BoundedPrim a+ascii4 cs =+  liftFixedToBounded $+  const cs >$< char8 >*< char8 >*< char8 >*< char8++{-# INLINE ascii5 #-}+ascii5 :: (Char, (Char, (Char, (Char, Char)))) -> BoundedPrim a+ascii5 cs =+  liftFixedToBounded $+  const cs >$< char8 >*< char8 >*< char8 >*< char8 >*< char8++{-# INLINE ascii6 #-}+ascii6 :: (Char, (Char, (Char, (Char, (Char, Char))))) -> BoundedPrim a+ascii6 cs =+  liftFixedToBounded $ +  const cs >$< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8++{-# INLINE ascii8 #-}+ascii8 :: (Char, (Char, (Char, (Char, (Char, (Char, (Char, Char))))))) -> BoundedPrim a+ascii8 cs =+  liftFixedToBounded $+  const cs >$< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8 >*< char8
+ library/JSONBytesBuilder/Private/ByteString/Builder.hs view
@@ -0,0 +1,66 @@+module JSONBytesBuilder.Private.ByteString.Builder+where++import JSONBytesBuilder.Private.Prelude hiding (length, null)+import Data.ByteString.Builder+import qualified JSONBytesBuilder.Private.ByteString.BoundedPrim as A+import qualified Data.ByteString.Builder.Prim as A+import qualified Data.Text.Encoding as B+import qualified Data.Scientific as C+import qualified Data.ByteString.Builder.Scientific as D+++{-# INLINABLE null #-}+null :: Builder+null =+  A.primBounded A.null ()++{-# INLINABLE boolean #-}+boolean :: Bool -> Builder+boolean =+  A.primBounded A.boolean++{-# INLINABLE string #-}+string :: Text -> Builder+string x =+  char8 '"' <> B.encodeUtf8BuilderEscaped A.stringEncodedByte x <> char8 '"'++{-# INLINABLE scientific #-}+scientific :: Scientific -> Builder+scientific n =+  if e < 0+    then D.scientificBuilder n+    else integerDec (C.coefficient n * 10 ^ e)+  where+    e =+      C.base10Exponent n++{-# INLINABLE inCurlies #-}+inCurlies :: Builder -> Builder+inCurlies x =+  char8 '{' <> x <> char8 '}'++{-# INLINABLE row #-}+row :: Text -> Builder -> Builder+row key value =+  string key <> char8 ':' <> value++{-# INLINABLE inSquarelies #-}+inSquarelies :: Builder -> Builder+inSquarelies x =+  char8 '[' <> x <> char8 ']'++{-# INLINABLE commaSeparated #-}+commaSeparated :: Builder -> Builder -> Builder+commaSeparated left right =+  left <> char8 ',' <> right++{-# INLINABLE emptyObject #-}+emptyObject :: Builder+emptyObject =+  A.primBounded A.emptyObject ()++{-# INLINABLE emptyArray #-}+emptyArray :: Builder+emptyArray =+  A.primBounded A.emptyArray ()
+ library/JSONBytesBuilder/Private/Prelude.hs view
@@ -0,0 +1,11 @@+module JSONBytesBuilder.Private.Prelude+(+  module Exports,+)+where++import BasePrelude as Exports hiding ((<>))+import Data.Semigroup as Exports (Semigroup(..))+import Data.Text as Exports (Text)+import Data.ByteString as Exports (ByteString)+import Data.Scientific as Exports (Scientific)