-
Notifications
You must be signed in to change notification settings - Fork 701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Json bytestring #7477
Json bytestring #7477
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
{-# LANGUAGE GADTs #-} | ||
{-# LANGUAGE OverloadedStrings #-} | ||
module UnitTests.Distribution.Utils.Json | ||
( tests | ||
) where | ||
|
||
import Distribution.Utils.Json | ||
|
||
import Test.Tasty | ||
import Test.Tasty.HUnit | ||
|
||
tests :: [TestTree] | ||
tests = | ||
[ testCase "escapes strings correctly" $ | ||
renderJson (JsonString "foo\"bar") @?= "\"foo\\\"bar\"" | ||
, testCase "renders empty list" $ | ||
renderJson (JsonArray []) @?= "[]" | ||
, testCase "renders singleton list" $ | ||
renderJson (JsonArray [JsonString "foo\"bar"]) @?= "[\"foo\\\"bar\"]" | ||
, testCase "renders list" $ | ||
renderJson (JsonArray [JsonString "foo\"bar", JsonString "baz"]) @?= "[\"foo\\\"bar\",\"baz\"]" | ||
, testCase "renders empty object" $ | ||
renderJson (JsonObject []) @?= "{}" | ||
, testCase "renders singleton object" $ | ||
renderJson (JsonObject [("key", JsonString "foo\"bar")]) @?= "{\"key\":\"foo\\\"bar\"}" | ||
, testCase "renders object" $ | ||
renderJson (JsonObject | ||
[ ("key", JsonString "foo\"bar") | ||
, ("key2", JsonString "baz")]) | ||
@?= "{\"key\":\"foo\\\"bar\",\"key2\":\"baz\"}" | ||
, testCase "renders number" $ | ||
renderJson (JsonNumber 0) @?= "0" | ||
, testCase "renders negative number" $ | ||
renderJson (JsonNumber (-1)) @?= "-1" | ||
, testCase "renders big number" $ | ||
renderJson (JsonNumber 5000000) @?= "5000000" | ||
, testCase "renders bool" $ do | ||
renderJson (JsonBool True) @?= "true" | ||
renderJson (JsonBool False) @?= "false" | ||
, testCase "renders null" $ do | ||
renderJson JsonNull @?= "null" | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,7 +75,7 @@ library | |
|
||
if !impl(ghc >= 7.8) | ||
-- semigroups depends on tagged. | ||
build-depends: tagged >=0.8.6 && <0.9 | ||
build-depends: tagged >=0.8.6 && <0.9, bytestring-builder >= 0.10.8 && <0.11 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From #6948 (comment)
Does that mean we don't need this dependency? Ill try to remove it and see whether CI is green. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I guess CI tells us that it is not fine. I still don't know why it is wrong though. @phadej Would you mind elaborating? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @phadej: ping? |
||
|
||
exposed-modules: | ||
Distribution.Backpack | ||
|
@@ -254,6 +254,7 @@ library | |
Distribution.Types.GivenComponent | ||
Distribution.Types.PackageVersionConstraint | ||
Distribution.Utils.Generic | ||
Distribution.Utils.Json | ||
Distribution.Utils.NubList | ||
Distribution.Utils.ShortText | ||
Distribution.Utils.Progress | ||
|
@@ -337,7 +338,6 @@ library | |
Distribution.Simple.GHC.EnvironmentParser | ||
Distribution.Simple.GHC.Internal | ||
Distribution.Simple.GHC.ImplInfo | ||
Distribution.Simple.Utils.Json | ||
Distribution.ZinzaPrelude | ||
Paths_Cabal | ||
|
||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
{-# LANGUAGE RankNTypes #-} | ||
{-# LANGUAGE OverloadedStrings #-} | ||
-- | Extremely simple JSON helper. Don't do anything too fancy with this! | ||
|
||
module Distribution.Utils.Json | ||
( Json(..) | ||
, (.=) | ||
, renderJson | ||
) where | ||
|
||
import Distribution.Compat.Prelude | ||
import qualified Data.ByteString.Lazy as LBS | ||
import Data.ByteString.Builder | ||
( Builder, stringUtf8, intDec, toLazyByteString ) | ||
|
||
data Json = JsonArray [Json] | ||
| JsonBool !Bool | ||
| JsonNull | ||
| JsonNumber !Int -- No support for Floats, Doubles just yet | ||
| JsonObject [(String, Json)] | ||
| JsonString !String | ||
deriving Show | ||
|
||
-- | Convert a 'Json' into a 'ByteString' | ||
renderJson :: Json -> LBS.ByteString | ||
renderJson json = toLazyByteString (go json) | ||
where | ||
go (JsonArray objs) = | ||
surround "[" "]" $ mconcat $ intersperse "," $ map go objs | ||
go (JsonBool True) = stringUtf8 "true" | ||
go (JsonBool False) = stringUtf8 "false" | ||
go JsonNull = stringUtf8 "null" | ||
go (JsonNumber n) = intDec n | ||
go (JsonObject attrs) = | ||
surround "{" "}" $ mconcat $ intersperse "," $ map render attrs | ||
where | ||
render (k,v) = (surround "\"" "\"" $ stringUtf8 (escape k)) <> ":" <> go v | ||
go (JsonString s) = surround "\"" "\"" $ stringUtf8 (escape s) | ||
|
||
surround :: Builder -> Builder -> Builder -> Builder | ||
surround begin end middle = mconcat [ begin , middle , end] | ||
|
||
escape :: String -> String | ||
escape ('\"':xs) = "\\\"" <> escape xs | ||
escape ('\\':xs) = "\\\\" <> escape xs | ||
escape ('\b':xs) = "\\b" <> escape xs | ||
escape ('\f':xs) = "\\f" <> escape xs | ||
escape ('\n':xs) = "\\n" <> escape xs | ||
escape ('\r':xs) = "\\r" <> escape xs | ||
escape ('\t':xs) = "\\t" <> escape xs | ||
escape (x:xs) = x : escape xs | ||
escape [] = mempty | ||
|
||
-- | A shorthand for building up 'JsonObject's | ||
-- >>> JsonObject [ "a" .= JsonNumber 42, "b" .= JsonBool True ] | ||
-- JsonObject [("a",JsonNumber 42),("b",JsonBool True)] | ||
(.=) :: String -> Json -> (String, Json) | ||
k .= v = (k, v) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Mikolaj, @emilypi Do we have some form of formatting standards for new code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's been no concrete discussion of standards. Don't worry about it for now, and we'll come up with one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. We only have https://github.com/haskell/cabal/blob/master/CONTRIBUTING.md#conventions, as mentioned in PR template. I guess, for now, use whatever conventions exist in the snippet you edit, unless they are utterly insane (in which case, create a reformatting commit first).