git.iko.soy/typeable/servant
on master help sign in
Merge pull request #1064 from DanBurton/lookup-response-header

Add lookupResponseHeader

commitdb80f41dee6208b13d1c2d696ffa2ae538bc07b4 authorOleg Grenrus <oleg.grenrus@iki.fi> dateThu 8 Nov 2018, 18:36 (8 years ago) parent05d0f7ee604b93
2 files changed+30−1
servant/src/Servant/API.hs+1−1 servant/src/Servant/API/ResponseHeaders.hs+29
servant/src/Servant/API.hs+1−1
@@ -112,7 +112,7 @@ import Servant.API.ResponseHeaders
112112 (AddHeader, BuildHeadersTo (buildHeadersTo),
113113 GetHeaders (getHeaders), HList (..), Headers (..),
114114 ResponseHeader (..), addHeader, getHeadersHList, getResponse,
115− noHeader)
115+ noHeader, HasResponseHeader, lookupResponseHeader)
116116import Servant.API.Stream
117117 (FramingRender (..), FramingUnrender (..),
118118 FromSourceIO (..), NetstringFraming, NewlineFraming,
servant/src/Servant/API/ResponseHeaders.hs+29
@@ -26,6 +26,8 @@ module Servant.API.ResponseHeaders
2626 , AddHeader
2727 , addHeader
2828 , noHeader
29+ , HasResponseHeader
30+ , lookupResponseHeader
2931 , BuildHeadersTo(buildHeadersTo)
3032 , GetHeaders(getHeaders)
3133 , GetHeaders'
@@ -183,6 +185,33 @@ addHeader = addOptionalHeader . Header
183185noHeader :: AddHeader h v orig new => orig -> new
184186noHeader = addOptionalHeader MissingHeader
185187
188+class HasResponseHeader h a headers where
189+ hlistLookupHeader :: HList headers -> ResponseHeader h a
190+
191+instance {-# OVERLAPPING #-} HasResponseHeader h a (Header h a ': rest) where
192+ hlistLookupHeader (HCons ha _) = ha
193+
194+instance {-# OVERLAPPABLE #-} (HasResponseHeader h a rest) => HasResponseHeader h a (first ': rest) where
195+ hlistLookupHeader (HCons _ hs) = hlistLookupHeader hs
196+
197+-- | Look up a specific ResponseHeader,
198+-- without having to know what position it is in the HList.
199+--
200+-- >>> let example1 = addHeader 5 "hi" :: Headers '[Header "someheader" Int] String
201+-- >>> let example2 = addHeader True example1 :: Headers '[Header "1st" Bool, Header "someheader" Int] String
202+-- >>> lookupResponseHeader example2 :: ResponseHeader "someheader" Int
203+-- Header 5
204+-- >>> lookupResponseHeader example2 :: ResponseHeader "1st" Bool
205+-- Header True
206+--
207+-- Usage of this function relies on an explicit type annotation of the header to be looked up.
208+-- This can be done with type annotations on the result, or with an explicit type application.
209+-- e.g.
210+-- @lookupResponseHeader \@"someheader" example2@
211+lookupResponseHeader :: (HasResponseHeader h a headers)
212+ => Headers headers r -> ResponseHeader h a
213+lookupResponseHeader = hlistLookupHeader . getHeadersHList
214+
186215-- $setup
187216-- >>> import Servant.API
188217-- >>> import Data.Aeson