buffer-builder 0.2.1.0 → 0.2.2.0
raw patch · 4 files changed
+91/−11 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.BufferBuilder.Json: class ToJson a => ToJsonString a
+ Data.BufferBuilder.Json: data JsonString
+ Data.BufferBuilder.Json: instance ToJson JsonString
+ Data.BufferBuilder.Json: instance ToJsonString JsonString
+ Data.BufferBuilder.Json: instance ToJsonString Text
+ Data.BufferBuilder.Json: row :: (ToJsonString k, ToJson v) => k -> v -> ObjectBuilder
+ Data.BufferBuilder.Json: toJsonString :: ToJsonString a => a -> JsonString
+ Data.BufferBuilder.Json: unsafeStringUtf8Builder :: Utf8Builder () -> JsonString
+ Data.BufferBuilder.Json: unsafeValueUtf8Builder :: Utf8Builder () -> Value
Files
- buffer-builder.cabal +1/−1
- changelog.md +7/−1
- src/Data/BufferBuilder/Json.hs +60/−9
- test/JsonTest.hs +23/−0
buffer-builder.cabal view
@@ -1,5 +1,5 @@ name: buffer-builder-version: 0.2.1.0+version: 0.2.2.0 synopsis: Library for efficiently building up buffers, one piece at a time description:
changelog.md view
@@ -1,3 +1,9 @@-0.2.0.4+0.2.2.0 +* Add the ability to encode custom types as JSON keys++0.2.1.0+ * Fix a buffer overrun in the double serializer+* Add support for URL percent-encoding+* Tweak the BufferWriter struct to improve code generation
src/Data/BufferBuilder/Json.hs view
@@ -23,11 +23,16 @@ , ToJson (..) , encodeJson + -- * Encoding Strings+ , JsonString+ , ToJsonString (..)+ -- * Objects , ObjectBuilder , emptyObject , (.=) , (.=#)+ , row -- * Arrays , array@@ -36,8 +41,12 @@ , nullValue -- * Unsafe- , unsafeAppendBS+ , unsafeValueUtf8Builder+ , unsafeStringUtf8Builder++ -- * Deprecated , unsafeAppendUtf8Builder+ , unsafeAppendBS ) where import GHC.Base@@ -62,7 +71,7 @@ -- from primitives like 'emptyObject', 'array', and 'null'. -- -- In special cases, or when performance is of utmost importance, the--- unsafe functions 'unsafeAppendBS' and 'unsafeAppendUtf8Builder' are+-- unsafe functions 'unsafeAppendUtf8Builder' are -- available. -- -- Internally, Value encodes an action or sequence of actions that append@@ -96,6 +105,17 @@ encodeJson = UB.runUtf8Builder . utf8Builder . toJson {-# INLINE encodeJson #-} +---- String++-- | Represents a JSON string.+newtype JsonString = JsonString { unJsonString :: Utf8Builder () }++-- | The class of types that can be converted to JSON strings. Any+-- type that provides ToJsonString also provides ToJson, and thus can+-- be used as JSON values.+class ToJson a => ToJsonString a where+ toJsonString :: a -> JsonString+ ---- Objects -- | Builds a JSON object.@@ -150,6 +170,16 @@ emptyObject = toJson NoPair {-# INLINE emptyObject #-} +-- | Create an ObjectBuilder from an arbitrary key and value. The key can be any+-- type with a 'ToJsonString' instance.+row :: (ToJsonString k, ToJson v) => k -> v -> ObjectBuilder+row k v = Pair $ do+ unJsonString $ toJsonString k+ UB.appendChar7 ':'+ utf8Builder $ toJson v+infixr 8 `row`+{-# INLINE row #-}+ -- | Create an 'ObjectBuilder' from a key and a value. (.=) :: ToJson a => Text -> a -> ObjectBuilder a .= b = Pair $ do@@ -298,7 +328,7 @@ instance ToJson Text where {-# INLINE toJson #-}- toJson txt = Value $ UB.appendEscapedJsonText txt+ toJson text = Value $ UB.appendEscapedJsonText text instance ToJson Double where {-# INLINE toJson #-}@@ -308,17 +338,38 @@ {-# INLINE toJson #-} toJson a = Value $ UB.appendDecimalSignedInt a +instance ToJsonString JsonString where+ toJsonString = id +instance ToJson JsonString where+ toJson = Value . unJsonString++instance ToJsonString Text where+ {-# INLINE toJsonString #-}+ toJsonString text = JsonString $ UB.appendEscapedJsonText text++ ---- Unsafe functions --- | Unsafely append a string into a JSON document.--- This function does /not/ escape, quote, or otherwise decorate the string in any way.+-- | Unsafely convert a 'Utf8Builder' into a JSON value.+-- This function does not escape, quote, or decorate the string in any way. -- This function is /unsafe/ because you can trivially use it to generate illegal JSON.-unsafeAppendBS :: ByteString -> Value-unsafeAppendBS bs = Value $ UB.unsafeAppendBS bs+unsafeValueUtf8Builder :: Utf8Builder () -> Value+unsafeValueUtf8Builder = Value --- | Unsafely append a 'Utf8Builder' into a JSON document.+-- | Unsafely convert a 'Utf8Builder' into a JSON string. -- This function does not escape, quote, or decorate the string in any way. -- This function is /unsafe/ because you can trivially use it to generate illegal JSON.+unsafeStringUtf8Builder :: Utf8Builder () -> JsonString+unsafeStringUtf8Builder = JsonString+++---- Deprecated++{-# DEPRECATED unsafeAppendBS "Use unsafeValueUtf8Builder or unsafeStringUtf8Builder instead" #-}+unsafeAppendBS :: ByteString -> Value+unsafeAppendBS bs = Value $ UB.unsafeAppendBS bs++{-# DEPRECATED unsafeAppendUtf8Builder "Use unsafeValueUtf8Builder or unsafeStringUtf8Builder instead" #-} unsafeAppendUtf8Builder :: Utf8Builder () -> Value-unsafeAppendUtf8Builder utf8b = Value utf8b+unsafeAppendUtf8Builder = unsafeValueUtf8Builder
test/JsonTest.hs view
@@ -11,6 +11,7 @@ import Data.Monoid ((<>), Monoid (mconcat, mempty)) import Data.String (IsString (..)) import Data.BufferBuilder.Json+import qualified Data.BufferBuilder.Utf8 as BBU import qualified Data.Aeson as Aeson import qualified Data.Aeson.Parser as JsonParse import qualified Data.ByteString as BS@@ -45,6 +46,28 @@ (encodeJson ("key" .= ("value" :: Text) <> "key2" .= ([5,6,7] :: [Int]))) ae "{}" $ encodeJson $ ((mempty :: ObjectBuilder) <> mempty) <> (mempty <> mempty) ae "[]" (encodeJson ([] :: [Int]))++data CustomThing = CustomThing++encodeCustomThing :: CustomThing -> BBU.Utf8Builder ()+encodeCustomThing _ = do+ BBU.appendChar7 '"'+ BBU.appendBS7 "foo"+ BBU.appendChar7 '/'+ BBU.appendBS7 "bar"+ BBU.appendChar7 '/'+ BBU.appendBS7 "baz"+ BBU.appendChar7 '"'++instance ToJson CustomThing where+ toJson = unsafeValueUtf8Builder . encodeCustomThing+instance ToJsonString CustomThing where+ toJsonString = unsafeStringUtf8Builder . encodeCustomThing++case_encode_object_with_custom_typeclasses :: IO ()+case_encode_object_with_custom_typeclasses = do+ ae "{\"key\":\"value\"}" $ encodeJson $ ("key" :: Text) `row` ("value" :: Text)+ ae "{\"foo/bar/baz\":\"foo/bar/baz\"}" $ encodeJson $ CustomThing `row` CustomThing case_monoid_laws :: IO () case_monoid_laws = do