module JSONBytesBuilder.Private.Builder where import JSONBytesBuilder.Private.Prelude hiding (null) import qualified Data.ByteString.Builder as A import qualified Data.Text.Lazy as C import qualified Data.ByteString.Lazy as D 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 Semigroup Rows where (<>) = \case Rows (Just left) -> \case Rows (Just right) -> Rows (Just (left <> A.char8 ',' <> right)) _ -> Rows (Just left) Rows Nothing -> id instance Monoid Rows where {-# INLINE mempty #-} mempty = Rows Nothing {-# INLINE mappend #-} mappend = (<>) -- | -- Builder of JSON Array elements. newtype Elements = Elements (Maybe A.Builder) instance Semigroup Elements where (<>) = \case Elements (Just left) -> \case Elements (Just right) -> Elements (Just (left <> A.char8 ',' <> right)) _ -> Elements (Just left) Elements Nothing -> id instance Monoid Elements where {-# INLINE mempty #-} mempty = Elements Nothing {-# INLINE mappend #-} mappend = (<>) -- | -- 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 numberFromInt #-} numberFromInt :: Int -> Literal numberFromInt = Literal . inline A.intDec -- | -- JSON Number literal from 'Integer'. {-# INLINE numberFromInteger #-} numberFromInteger :: Integer -> Literal numberFromInteger = Literal . inline A.integerDec -- | -- JSON Number literal from 'Double'. {-# INLINE numberFromDouble #-} numberFromDouble :: Double -> Literal numberFromDouble = Literal . inline A.doubleDec -- | -- JSON Number literal from 'Scientific'. {-# INLINE numberFromScientific #-} numberFromScientific :: Scientific -> Literal numberFromScientific = Literal . inline E.scientific -- | -- JSON String literal from 'Text' encoded using UTF8. {-# INLINE stringFromText #-} stringFromText :: Text -> Literal stringFromText = Literal . inline E.stringFromText -- | -- JSON String literal from lazy Text encoded using UTF8. {-# INLINE stringFromLazyText #-} stringFromLazyText :: C.Text -> Literal stringFromLazyText = Literal . inline E.stringFromLazyText -- | -- JSON String literal from 'ByteString' with only escaping applied to it. {-# INLINE stringFromBytes #-} stringFromBytes :: ByteString -> Literal stringFromBytes = Literal . inline E.stringFromBytes -- | -- JSON String literal from lazy ByteString with only escaping applied to it. {-# INLINE stringFromLazyBytes #-} stringFromLazyBytes :: D.ByteString -> Literal stringFromLazyBytes = Literal . inline E.stringFromLazyBytes -- | -- JSON Object literal from the 'Rows' builder. {-# INLINE object #-} object :: Rows -> Literal object (Rows x) = Literal (maybe E.emptyObject (inline E.inCurlies) x) -- | -- JSON Object literal from a list of rows. -- A convienience shortcut to @object . mconcat@ for typical cases. {-# INLINE objectFromRows #-} objectFromRows :: [Rows] -> Literal objectFromRows = object . mconcat -- | -- JSON Array literal from the 'Elements' builder. {-# INLINE array #-} array :: Elements -> Literal array (Elements x) = Literal (maybe E.emptyArray (inline E.inSquarelies) x) -- | -- JSON Array literal from a list of element literals. -- A convienience shortcut to @array . foldMap element@ for typical cases. arrayFromLiterals :: [Literal] -> Literal arrayFromLiterals = array . foldMap element -- | -- 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)