Skip to content

Commit 459ecef

Browse files
authored
Merge pull request #1695 from haskell-servant/maksbotan/aeson-2.2
Allow aeson-2.2
2 parents a14cd7e + 8a4a7f5 commit 459ecef

File tree

6 files changed

+23
-51
lines changed

6 files changed

+23
-51
lines changed

.github/workflows/master.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ name: CI
33
on:
44
pull_request:
55
push:
6+
branches:
7+
- master
68

79
jobs:
810
cabal:
@@ -20,6 +22,7 @@ jobs:
2022
- "9.2.8"
2123
- "9.4.5"
2224
- "9.6.2"
25+
fail-fast: false
2326

2427
steps:
2528
- uses: actions/checkout@v2

doc/tutorial/Server.lhs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ import System.Directory
4747
import Text.Blaze
4848
import Text.Blaze.Html.Renderer.Utf8
4949
import Servant.Types.SourceT (source)
50-
import qualified Data.Aeson.Parser
5150
import qualified Text.Blaze.Html
5251
```
5352
@@ -431,25 +430,11 @@ class Accept ctype => MimeUnrender ctype a where
431430
mimeUnrender :: Proxy ctype -> ByteString -> Either String a
432431
```
433432
434-
We don't have much work to do there either, `Data.Aeson.eitherDecode` is
435-
precisely what we need. However, it only allows arrays and objects as toplevel
436-
JSON values and this has proven to get in our way more than help us so we wrote
437-
our own little function around **aeson** and **attoparsec** that allows any type of
438-
JSON value at the toplevel of a "JSON document". Here's the definition in case
439-
you are curious.
440-
441-
``` haskell
442-
eitherDecodeLenient :: FromJSON a => ByteString -> Either String a
443-
eitherDecodeLenient input = do
444-
v :: Value <- parseOnly (Data.Aeson.Parser.value <* endOfInput) (cs input)
445-
parseEither parseJSON v
446-
```
447-
448-
This function is exactly what we need for our `MimeUnrender` instance.
433+
As with `MimeRender`, we can use a function already available in `aeson`: `Data.Aeson.eitherDecode`.
449434
450435
``` haskell ignore
451436
instance FromJSON a => MimeUnrender JSON a where
452-
mimeUnrender _ = eitherDecodeLenient
437+
mimeUnrender _ = eitherDecode
453438
```
454439
455440
And this is all the code that lets you use `JSON` with `ReqBody`, `Get`,

servant/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
Package versions follow the [Package Versioning Policy](https://pvp.haskell.org/): in A.B.C, bumps to either A or B represent major versions.
44

5+
0.20.1
6+
----
7+
8+
- Support aeson-2.2 [#1695](https://github.com/haskell-servant/servant/pull/1695)
9+
510
0.20
611
----
712

servant/servant.cabal

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 2.2
22
name: servant
3-
version: 0.20
3+
version: 0.20.1
44

55
synopsis: A family of combinators for defining webservices APIs
66
category: Servant, Web
@@ -100,7 +100,7 @@ library
100100
-- Here can be exceptions if we really need features from the newer versions.
101101
build-depends:
102102
base-compat >= 0.10.5 && < 0.14
103-
, aeson >= 1.4.1.0 && < 2.2
103+
, aeson >= 1.4.1.0 && < 2.3
104104
, attoparsec >= 0.13.2.2 && < 0.15
105105
, bifunctors >= 5.5.3 && < 5.7
106106
, case-insensitive >= 1.2.0.11 && < 1.3

servant/src/Servant/API/ContentTypes.hs

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,7 @@ import Control.Monad.Compat
7575
import Control.DeepSeq
7676
(NFData)
7777
import Data.Aeson
78-
(FromJSON (..), ToJSON (..), encode)
79-
import Data.Aeson.Parser
80-
(value)
81-
import Data.Aeson.Types
82-
(parseEither)
83-
import Data.Attoparsec.ByteString.Char8
84-
(endOfInput, parseOnly, skipSpace, (<?>))
78+
(FromJSON (..), ToJSON (..), encode, eitherDecode)
8579
import Data.Bifunctor
8680
(bimap)
8781
import qualified Data.ByteString as BS
@@ -371,28 +365,15 @@ instance NFData NoContent
371365
--------------------------------------------------------------------------
372366
-- * MimeUnrender Instances
373367

374-
-- | Like 'Data.Aeson.eitherDecode' but allows all JSON values instead of just
375-
-- objects and arrays.
368+
-- | Deprecated: since aeson version 0.9 `eitherDecode` has lenient behavior.
376369
--
377-
-- Will handle trailing whitespace, but not trailing junk. ie.
378-
--
379-
-- >>> eitherDecodeLenient "1 " :: Either String Int
380-
-- Right 1
381-
--
382-
-- >>> eitherDecodeLenient "1 junk" :: Either String Int
383-
-- Left "trailing junk after valid JSON: endOfInput"
384370
eitherDecodeLenient :: FromJSON a => ByteString -> Either String a
385-
eitherDecodeLenient input =
386-
parseOnly parser (cs input) >>= parseEither parseJSON
387-
where
388-
parser = skipSpace
389-
*> Data.Aeson.Parser.value
390-
<* skipSpace
391-
<* (endOfInput <?> "trailing junk after valid JSON")
371+
eitherDecodeLenient = eitherDecode
372+
{-# DEPRECATED eitherDecodeLenient "use eitherDecode instead" #-}
392373

393374
-- | `eitherDecode`
394375
instance FromJSON a => MimeUnrender JSON a where
395-
mimeUnrender _ = eitherDecodeLenient
376+
mimeUnrender _ = eitherDecode
396377

397378
-- | @urlDecodeAsForm@
398379
-- Note that the @mimeUnrender p (mimeRender p x) == Right x@ law only

servant/test/Servant/API/ContentTypesSpec.hs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Prelude ()
1212
import Prelude.Compat
1313

1414
import Data.Aeson
15-
(FromJSON, ToJSON (..), Value, decode, encode, object, (.=))
15+
(FromJSON, ToJSON (..), Value, decode, encode, object, (.=), eitherDecode)
1616
import Data.ByteString.Char8
1717
(ByteString, append, pack)
1818
import qualified Data.ByteString.Lazy as BSL
@@ -219,15 +219,13 @@ spec = describe "Servant.API.ContentTypes" $ do
219219
handleCTypeH (Proxy :: Proxy '[JSONorText]) "image/jpeg"
220220
"foobar" `shouldBe` (Nothing :: Maybe (Either String Int))
221221

222-
-- aeson >= 0.9 decodes top-level strings
223-
describe "eitherDecodeLenient" $ do
222+
describe "eitherDecode is lenient" $ do
224223

224+
-- Since servant-0.20.1 MimeUnrender JSON instance uses eitherDecode,
225+
-- as aeson >= 0.9 supports decoding top-level strings and numbers.
225226
it "parses top-level strings" $ do
226-
let toMaybe = either (const Nothing) Just
227-
-- The Left messages differ, so convert to Maybe
228-
property $ \x -> toMaybe (eitherDecodeLenient x)
229-
`shouldBe` (decode x :: Maybe String)
230-
227+
property $ \x -> mimeUnrender (Proxy :: Proxy JSON) x
228+
`shouldBe` (eitherDecode x :: Either String String)
231229

232230
data SomeData = SomeData { record1 :: String, record2 :: Int }
233231
deriving (Generic, Eq, Show)

0 commit comments

Comments
 (0)