Skip to content

Commit

Permalink
Merge branch 'issue-cdepillabout#5-simplify-instances' into custom
Browse files Browse the repository at this point in the history
  • Loading branch information
lexi-lambda committed May 3, 2017
2 parents ebe7ffa + 83950b8 commit 3a29f64
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 19 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ $ curl \
--request POST \
--header 'Accept: application/json' \
'http://localhost:8201/lax-search/hello'
{"data":"good"}
"good"
```

If you try to send a query that is not `hello`, the server will return an error:
Expand All @@ -132,7 +132,7 @@ $ curl \
--request POST \
--header 'Accept: application/json' \
'http://localhost:8201/lax-search/hello'
{"err":"BadSearchTermErr"}
"BadSearchTermErr"
```

There is also a strict api, that requires `hello` to be capitalized like `Hello`:
Expand All @@ -142,12 +142,12 @@ $ curl \
--request POST \
--header 'Accept: application/json' \
'http://localhost:8201/strict-search/hello'
{"err":"IncorrectCapitalization"}
"IncorrectCapitalization"
$ curl \
--request POST \
--header 'Accept: application/json' \
'http://localhost:8201/strict-search/Hello'
{"data":"good"}
"good"
```

### Run the client
Expand Down Expand Up @@ -202,11 +202,11 @@ search api:

- This is a successful response.

{"data":"good"}
"good"

- a completely incorrect search term was used

{"err":"BadSearchTermErr"}
"BadSearchTermErr"
```

You can see that both the success and error responses are documented.
23 changes: 10 additions & 13 deletions src/Servant/Checked/Exceptions/Internal/Envelope.hs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ module Servant.Checked.Exceptions.Internal.Envelope
import Control.Applicative ((<|>))
import Control.Lens (Iso, Prism, Prism', iso, preview, prism)
import Control.Monad.Fix (MonadFix(mfix))
import Data.Aeson
(FromJSON(parseJSON), ToJSON(toJSON), Value, (.=), (.:), object,
withObject)
import Data.Aeson (FromJSON(parseJSON), ToJSON(toJSON), Value)
import Data.Aeson.Types (Parser)
import Data.Data (Data)
import Data.Semigroup (Semigroup((<>), stimes), stimesIdempotent)
Expand Down Expand Up @@ -388,37 +386,36 @@ catchesEnvelope tuple _ (ErrEnvelope u) = catchesOpenUnion tuple u

-- data EnvelopeHandler es x = forall e. IsMember e es => EnvelopeHandler (e -> x)

-- | This 'ToJSON' instance encodes an 'Envelope' as an object with one of two
-- keys depending on whether it is a 'SuccEnvelope' or an 'ErrEnvelope'.
-- | This 'ToJSON' instance simply encodes an 'Envelope' by deferring directly
-- to the instances for the @es@ and @a@, without any additional wrapping.
--
-- Here is an example of a 'SuccEnvelope':
--
-- >>> let string = "hello" :: String
-- >>> let env = toSuccEnvelope string :: Envelope '[Double] String
-- >>> putByteStrLn $ encode env
-- {"data":"hello"}
-- "hello"
--
-- Here is an example of a 'ErrEnvelope':
--
-- >>> let double = 3.5 :: Double
-- >>> let env' = toErrEnvelope double :: Envelope '[Double] String
-- >>> putByteStrLn $ encode env'
-- {"err":3.5}
-- 3.5
instance (ToJSON (OpenUnion es), ToJSON a) => ToJSON (Envelope es a) where
toJSON :: Envelope es a -> Value
toJSON (ErrEnvelope es) = object ["err" .= es]
toJSON (SuccEnvelope a) = object ["data" .= a]
toJSON (ErrEnvelope es) = toJSON es
toJSON (SuccEnvelope a) = toJSON a

-- | This is only a valid instance when the 'FromJSON' instances for the @es@
-- don't overlap.
-- and @a@ don't overlap.
--
-- For an explanation, see the documentation on the 'FromJSON' instance for
-- 'Union'.
instance (FromJSON (OpenUnion es), FromJSON a) => FromJSON (Envelope es a) where
parseJSON :: Value -> Parser (Envelope es a)
parseJSON = withObject "Envelope" $ \obj ->
SuccEnvelope <$> obj .: "data" <|>
ErrEnvelope <$> obj .: "err"
parseJSON val = SuccEnvelope <$> parseJSON val
<|> ErrEnvelope <$> parseJSON val

deriving instance (Data (OpenUnion es), Data a, Typeable es) => Data (Envelope es a)
deriving instance (Eq (OpenUnion es), Eq a) => Eq (Envelope es a)
Expand Down

0 comments on commit 3a29f64

Please sign in to comment.