on master help sign in
Add HasStatus instance for Headers (that defers StatusOf to underlying value) (#1649)
a2e0033Intolerable
changelog.d/1649new file+8
@@ -0,0 +1,8 @@
1+synopsis: Add HasStatus instance for Headers (that defers StatusOf to underlying value)
2+prs: #1649
3+
4+description: {
5+
6+Adds a new HasStatus (Headers hs a) instance (StatusOf (Headers hs a) = StatusOf a)
7+
8+}
servant/src/Servant/API/UVerb.hs+4
@@ -38,6 +38,7 @@ import GHC.TypeLits (Nat)
38import Network.HTTP.Types (Status, StdMethod)
38import Network.HTTP.Types (Status, StdMethod)
39import Servant.API.ContentTypes (JSON, PlainText, FormUrlEncoded, OctetStream, NoContent, MimeRender(mimeRender), MimeUnrender(mimeUnrender))
39import Servant.API.ContentTypes (JSON, PlainText, FormUrlEncoded, OctetStream, NoContent, MimeRender(mimeRender), MimeUnrender(mimeUnrender))
40import Servant.API.Status (KnownStatus, statusVal)
40import Servant.API.Status (KnownStatus, statusVal)
41+import Servant.API.ResponseHeaders (Headers)
41import Servant.API.UVerb.Union
42import Servant.API.UVerb.Union
42
43
43class KnownStatus (StatusOf a) => HasStatus (a :: *) where
44class KnownStatus (StatusOf a) => HasStatus (a :: *) where
@@ -52,6 +53,9 @@ statusOf = const (statusVal (Proxy :: Proxy (StatusOf a)))
52instance HasStatus NoContent where
53instance HasStatus NoContent where
53 type StatusOf NoContent = 204
54 type StatusOf NoContent = 204
54
55
56+instance HasStatus a => HasStatus (Headers hs a) where
57+ type StatusOf (Headers hs a) = StatusOf a
58+
55class HasStatuses (as :: [*]) where
59class HasStatuses (as :: [*]) where
56 type Statuses (as :: [*]) :: [Nat]
60 type Statuses (as :: [*]) :: [Nat]
57 statuses :: Proxy as -> [Status]
61 statuses :: Proxy as -> [Status]
servant/test/Servant/API/ResponseHeadersSpec.hs+11
@@ -2,10 +2,14 @@
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Servant.API.ResponseHeadersSpec where
3module Servant.API.ResponseHeadersSpec where
4
4
5+import Data.Proxy
6+import GHC.TypeLits
5import Test.Hspec
7import Test.Hspec
6
8
9+import Servant.API.ContentTypes
7import Servant.API.Header
10import Servant.API.Header
8import Servant.API.ResponseHeaders
11import Servant.API.ResponseHeaders
12+import Servant.API.UVerb
9
13
10spec :: Spec
14spec :: Spec
11spec = describe "Servant.API.ResponseHeaders" $ do
15spec = describe "Servant.API.ResponseHeaders" $ do
@@ -28,3 +32,10 @@ spec = describe "Servant.API.ResponseHeaders" $ do
28 it "does not add a header" $ do
32 it "does not add a header" $ do
29 let val = noHeader 5 :: Headers '[Header "test" Int] Int
33 let val = noHeader 5 :: Headers '[Header "test" Int] Int
30 getHeaders val `shouldBe` []
34 getHeaders val `shouldBe` []
35+
36+ describe "HasStatus Headers" $ do
37+
38+ it "gets the status from the underlying value" $ do
39+ natVal (Proxy :: Proxy (StatusOf (Headers '[Header "first" Int] NoContent))) `shouldBe` 204
40+ natVal (Proxy :: Proxy (StatusOf (Headers '[Header "first" Int] (WithStatus 503 ())))) `shouldBe` 503
41+