-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A web framework that integrates Servant, RIO, EKG, fast-logger, wai-cli… -- -- Inspired by Dropwizard, Magicbane provides a packaged framework for -- developing web services using the best available libraries, including -- Servant, RIO, Aeson, EKG/monad-metrics, fast-logger, wai-cli and -- others. @package magicbane @version 0.4.0 -- | Extends Servant with context, based on RIO. The context should be a -- tuple of all your moudles and configs and stuff, so that the Data.Has -- module would let you access these items by type. module Magicbane.App -- | asProxyTypeOf is a type-restricted version of const. It -- is usually used as an infix operator, and its typing forces its first -- argument (which is usually overloaded) to have the same type as the -- tag of the second. -- --
--   >>> import Data.Word
--   
--   >>> :type asProxyTypeOf 123 (Proxy :: Proxy Word8)
--   asProxyTypeOf 123 (Proxy :: Proxy Word8) :: Word8
--   
-- -- Note the lower-case proxy in the definition. This allows any -- type constructor with just one argument to be passed to the function, -- for example we could also write -- --
--   >>> import Data.Word
--   
--   >>> :type asProxyTypeOf 123 (Just (undefined :: Word8))
--   asProxyTypeOf 123 (Just (undefined :: Word8)) :: Word8
--   
asProxyTypeOf :: () => a -> proxy a -> a -- | Proxy is a type that holds no data, but has a phantom parameter -- of arbitrary type (or even kind). Its use is to provide type -- information, even though there is no value available of that type (or -- it may be too costly to create one). -- -- Historically, Proxy :: Proxy a is a safer -- alternative to the 'undefined :: a' idiom. -- --
--   >>> Proxy :: Proxy (Void, Int -> Int)
--   Proxy
--   
-- -- Proxy can even hold types of higher kinds, -- --
--   >>> Proxy :: Proxy Either
--   Proxy
--   
-- --
--   >>> Proxy :: Proxy Functor
--   Proxy
--   
-- --
--   >>> Proxy :: Proxy complicatedStructure
--   Proxy
--   
data Proxy (t :: k) :: forall k. () => k -> * Proxy :: Proxy -- | A concrete, promotable proxy type, for use at the kind level There are -- no instances for this because it is intended at the kind level only data KProxy t KProxy :: KProxy t -- | Type-level If. If True a b ==> a; If -- False a b ==> b -- | Convert value to HTTP API data. -- -- WARNING: Do not derive this using DeriveAnyClass as -- the generated instance will loop indefinitely. class ToHttpApiData a -- | Convert to URL path piece. toUrlPiece :: ToHttpApiData a => a -> Text -- | Convert to a URL path piece, making sure to encode any special chars. -- The default definition uses encodePathSegmentsRelative, but -- this may be overriden with a more efficient version. toEncodedUrlPiece :: ToHttpApiData a => a -> Builder -- | Convert to HTTP header value. toHeader :: ToHttpApiData a => a -> ByteString -- | Convert to query param value. toQueryParam :: ToHttpApiData a => a -> Text -- | Parse value from HTTP API data. -- -- WARNING: Do not derive this using DeriveAnyClass as -- the generated instance will loop indefinitely. class FromHttpApiData a -- | Parse URL path piece. parseUrlPiece :: FromHttpApiData a => Text -> Either Text a -- | Parse HTTP header value. parseHeader :: FromHttpApiData a => ByteString -> Either Text a -- | Parse query param value. parseQueryParam :: FromHttpApiData a => Text -> Either Text a -- | Represents a general universal resource identifier using its component -- parts. -- -- For example, for the URI -- --
--   foo://anonymous@www.haskell.org:42/ghc?query#frag
--   
-- -- the components are: data URI URI :: String -> Maybe URIAuth -> String -> String -> String -> URI -- |
--   foo:
--   
[uriScheme] :: URI -> String -- |
--   //anonymous@www.haskell.org:42
--   
[uriAuthority] :: URI -> Maybe URIAuth -- |
--   /ghc
--   
[uriPath] :: URI -> String -- |
--   ?query
--   
[uriQuery] :: URI -> String -- |
--   #frag
--   
[uriFragment] :: URI -> String -- | HTTP Version. -- -- Note that the Show instance is intended merely for debugging. data HttpVersion HttpVersion :: !Int -> !Int -> HttpVersion [httpMajor] :: HttpVersion -> !Int [httpMinor] :: HttpVersion -> !Int -- | HTTP standard method (as defined by RFC 2616, and PATCH which is -- defined by RFC 5789). data StdMethod GET :: StdMethod POST :: StdMethod HEAD :: StdMethod PUT :: StdMethod DELETE :: StdMethod TRACE :: StdMethod CONNECT :: StdMethod OPTIONS :: StdMethod PATCH :: StdMethod -- | Is used within a monadic computation to begin exception processing. throwError :: MonadError e m => e -> m a -- | More general version of allFieldLinks. allFieldLinks' :: (HasLink ToServantApi routes, GenericServant routes AsLink a, ToServant routes AsLink a ~ MkLink ToServantApi routes a) => Link -> a -> routes AsLink a -- | Get all links as a record. allFieldLinks :: (HasLink ToServantApi routes, GenericServant routes AsLink Link, ToServant routes AsLink Link ~ MkLink ToServantApi routes Link) => routes AsLink Link -- | More general version of fieldLink fieldLink' :: (IsElem endpoint ToServantApi routes, HasLink endpoint, GenericServant routes AsApi) => Link -> a -> routes AsApi -> endpoint -> MkLink endpoint a -- | Given an API record field, create a link for that route. Only the -- field's type is used. -- --
--   data Record route = Record
--       { _get :: route :- Capture "id" Int :> Get '[JSON] String
--       , _put :: route :- ReqBody '[JSON] Int :> Put '[JSON] Bool
--       }
--     deriving (Generic)
--   
--   getLink :: Int -> Link
--   getLink = fieldLink _get
--   
fieldLink :: (IsElem endpoint ToServantApi routes, HasLink endpoint, GenericServant routes AsApi) => routes AsApi -> endpoint -> MkLink endpoint Link -- | More general allLinks. See safeLink'. allLinks' :: HasLink api => Link -> a -> Proxy api -> MkLink api a -- | Create all links in an API. -- -- Note that the api type must be restricted to the endpoints -- that have valid links to them. -- --
--   >>> type API = "foo" :> Capture "name" Text :> Get '[JSON] Text :<|> "bar" :> Capture "name" Int :> Get '[JSON] Double
--   
--   >>> let fooLink :<|> barLink = allLinks (Proxy :: Proxy API)
--   
--   >>> :t fooLink
--   fooLink :: Text -> Link
--   
--   >>> :t barLink
--   barLink :: Int -> Link
--   
-- -- Note: nested APIs don't work well with this approach -- --
--   >>> :kind! MkLink (Capture "nest" Char :> (Capture "x" Int :> Get '[JSON] Int :<|> Capture "y" Double :> Get '[JSON] Double)) Link
--   MkLink (Capture "nest" Char :> (Capture "x" Int :> Get '[JSON] Int :<|> Capture "y" Double :> Get '[JSON] Double)) Link :: *
--   = Char -> (Int -> Link) :<|> (Double -> Link)
--   
allLinks :: HasLink api => Proxy api -> MkLink api Link -- | More general safeLink. safeLink' :: (IsElem endpoint api, HasLink endpoint) => Link -> a -> Proxy api -> Proxy endpoint -> MkLink endpoint a -- | Create a valid (by construction) relative URI with query params. -- -- This function will only typecheck if endpoint is part of the -- API api safeLink :: (IsElem endpoint api, HasLink endpoint) => Proxy api -> Proxy endpoint -> MkLink endpoint Link -- | Configurable linkURI. -- --
--   >>> type API = "sum" :> QueryParams "x" Int :> Get '[JSON] Int
--   
--   >>> linkURI' LinkArrayElementBracket $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API) [1, 2, 3]
--   sum?x[]=1&x[]=2&x[]=3
--   
-- --
--   >>> linkURI' LinkArrayElementPlain $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API) [1, 2, 3]
--   sum?x=1&x=2&x=3
--   
linkURI' :: LinkArrayElementStyle -> Link -> URI -- | Transform Link into URI. -- --
--   >>> type API = "something" :> Get '[JSON] Int
--   
--   >>> linkURI $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API)
--   something
--   
-- --
--   >>> type API = "sum" :> QueryParams "x" Int :> Get '[JSON] Int
--   
--   >>> linkURI $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API) [1, 2, 3]
--   sum?x[]=1&x[]=2&x[]=3
--   
-- --
--   >>> type API = "foo/bar" :> Get '[JSON] Int
--   
--   >>> linkURI $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API)
--   foo%2Fbar
--   
-- --
--   >>> type SomeRoute = "abc" :> Capture "email" String :> Put '[JSON] ()
--   
--   >>> let someRoute = Proxy :: Proxy SomeRoute
--   
--   >>> safeLink someRoute someRoute "test@example.com"
--   Link {_segments = ["abc","test%40example.com"], _queryParams = []}
--   
-- --
--   >>> linkURI $ safeLink someRoute someRoute "test@example.com"
--   abc/test%40example.com
--   
linkURI :: Link -> URI linkQueryParams :: Link -> [Param] linkSegments :: Link -> [String] -- | A safe link datatype. The only way of constructing a Link is -- using safeLink, which means any Link is guaranteed to be -- part of the mentioned API. data Link -- | Query parameter. data Param SingleParam :: String -> Text -> Param ArrayElemParam :: String -> Text -> Param FlagParam :: String -> Param -- | How to encode array query elements. data LinkArrayElementStyle -- |
--   foo[]=1&foo[]=2
--   
LinkArrayElementBracket :: LinkArrayElementStyle -- |
--   foo=1&foo=2
--   
LinkArrayElementPlain :: LinkArrayElementStyle -- | A type that specifies that an API record contains a set of links. data AsLink a -- | Construct a toLink for an endpoint. class HasLink (endpoint :: k) where { type family MkLink (endpoint :: k) a :: *; } toLink :: HasLink endpoint => Link -> a -> Proxy endpoint -> Link -> MkLink endpoint a -- | WithNamedContext names a specific tagged context to use for the -- combinators in the API. (See also in servant-server, -- Servant.Server.Context.) For example: -- --
--   type UseNamedContextAPI = WithNamedContext "myContext" '[String] (
--       ReqBody '[JSON] Int :> Get '[JSON] Int)
--   
-- -- Both the ReqBody and Get combinators will use the -- WithNamedContext with type tag "myContext" as their context. -- -- Contexts are only relevant for servant-server. -- -- For more information, see the tutorial. data WithNamedContext (name :: Symbol) (subContext :: [*]) subApi -- | Flatten API into a list of endpoints. -- --
--   >>> Refl :: Endpoints SampleAPI :~: '["hello" :> Verb 'GET 200 '[JSON] Int, "bye" :> (Capture "name" String :> Verb 'POST 200 '[JSON, PlainText] Bool)]
--   Refl
--   
-- | You may use this type family to tell the type checker that your custom -- type may be skipped as part of a link. This is useful for things like -- QueryParam that are optional in a URI and do not -- affect them if they are omitted. -- --
--   >>> data CustomThing
--   
--   >>> type instance IsElem' e (CustomThing :> s) = IsElem e s
--   
-- -- Note that IsElem is called, which will mutually -- recurse back to IsElem' if it exhausts all other -- options again. -- -- Once you have written a HasLink instance for -- CustomThing you are ready to go. -- | Closed type family, check if endpoint is within api. -- Uses IsElem' if it exhausts all other options. -- --
--   >>> ok (Proxy :: Proxy (IsElem ("hello" :> Get '[JSON] Int) SampleAPI))
--   OK
--   
-- --
--   >>> ok (Proxy :: Proxy (IsElem ("bye" :> Get '[JSON] Int) SampleAPI))
--   ...
--   ... Could not deduce...
--   ...
--   
-- -- An endpoint is considered within an api even if it is missing -- combinators that don't affect the URL: -- --
--   >>> ok (Proxy :: Proxy (IsElem (Get '[JSON] Int) (Header "h" Bool :> Get '[JSON] Int)))
--   OK
--   
-- --
--   >>> ok (Proxy :: Proxy (IsElem (Get '[JSON] Int) (ReqBody '[JSON] Bool :> Get '[JSON] Int)))
--   OK
--   
-- -- -- | Check whether sub is a sub-API of api. -- --
--   >>> ok (Proxy :: Proxy (IsSubAPI SampleAPI (SampleAPI :<|> Get '[JSON] Int)))
--   OK
--   
-- --
--   >>> ok (Proxy :: Proxy (IsSubAPI (SampleAPI :<|> Get '[JSON] Int) SampleAPI))
--   ...
--   ... Could not deduce...
--   ...
--   
-- -- This uses IsElem for checking; thus the note there applies -- here. -- | Check that every element of xs is an endpoint of api -- (using IsElem). -- | Closed type family, check if endpoint is exactly within -- api. -- --
--   >>> ok (Proxy :: Proxy (IsIn ("hello" :> Get '[JSON] Int) SampleAPI))
--   OK
--   
-- -- Unlike IsElem, this requires an *exact* match. -- --
--   >>> ok (Proxy :: Proxy (IsIn (Get '[JSON] Int) (Header "h" Bool :> Get '[JSON] Int)))
--   ...
--   ... Could not deduce...
--   ...
--   
-- | Check whether sub is a sub API of api. -- -- Like IsSubAPI, but uses IsIn rather than IsElem. -- | Check that every element of xs is an endpoint of api -- (using IsIn). -- -- ok (Proxy :: Proxy (AllIsIn (Endpoints SampleAPI) SampleAPI)) OK -- | Apply (e :>) to every API in xs. -- | Append two type-level lists. -- | Check that a value is an element of a list: -- --
--   >>> ok (Proxy :: Proxy (Elem Bool '[Int, Bool]))
--   OK
--   
-- --
--   >>> ok (Proxy :: Proxy (Elem String '[Int, Bool]))
--   ...
--   ... [Char]...'[Int, Bool...
--   ...
--   
type Elem (e :: t) (es :: [t]) = ElemGo e es es -- | If either a or b produce an empty constraint, produce an empty -- constraint. -- | Verb is a general type for representing HTTP verbs (a.k.a. -- methods). For convenience, type synonyms for each verb with a 200 -- response code are provided, but you are free to define your own: -- --
--   >>> type Post204 contentTypes a = Verb 'POST 204 contentTypes a
--   
data Verb (method :: k1) (statusCode :: Nat) (contentTypes :: [*]) a :: forall k1. () => k1 -> Nat -> [*] -> * -> * -- | GET with 200 status code. type Get = Verb GET 200 -- | POST with 200 status code. type Post = Verb POST 200 -- | PUT with 200 status code. type Put = Verb PUT 200 -- | DELETE with 200 status code. type Delete = Verb DELETE 200 -- | PATCH with 200 status code. type Patch = Verb PATCH 200 -- | POST with 201 status code. type PostCreated = Verb POST 201 -- | GET with 202 status code. type GetAccepted = Verb GET 202 -- | POST with 202 status code. type PostAccepted = Verb POST 202 -- | DELETE with 202 status code. type DeleteAccepted = Verb DELETE 202 -- | PATCH with 202 status code. type PatchAccepted = Verb PATCH 202 -- | PUT with 202 status code. type PutAccepted = Verb PUT 202 -- | GET with 203 status code. type GetNonAuthoritative = Verb GET 203 -- | POST with 203 status code. type PostNonAuthoritative = Verb POST 203 -- | DELETE with 203 status code. type DeleteNonAuthoritative = Verb DELETE 203 -- | PATCH with 203 status code. type PatchNonAuthoritative = Verb PATCH 203 -- | PUT with 203 status code. type PutNonAuthoritative = Verb PUT 203 -- | GET with 204 status code. type GetNoContent = Verb GET 204 -- | POST with 204 status code. type PostNoContent = Verb POST 204 -- | DELETE with 204 status code. type DeleteNoContent = Verb DELETE 204 -- | PATCH with 204 status code. type PatchNoContent = Verb PATCH 204 -- | PUT with 204 status code. type PutNoContent = Verb PUT 204 -- | GET with 205 status code. type GetResetContent = Verb GET 205 -- | POST with 205 status code. type PostResetContent = Verb POST 205 -- | GET with 206 status code. type GetPartialContent = Verb GET 206 class ReflectMethod (a :: k) reflectMethod :: ReflectMethod a => Proxy a -> Method -- | The contained API (second argument) can be found under ("/" ++ -- path) (path being the first argument). -- -- Example: -- --
--   >>> -- GET /hello/world
--   
--   >>> -- returning a JSON encoded World value
--   
--   >>> type MyApi = "hello" :> "world" :> Get '[JSON] World
--   
data (:>) (path :: k) a :: forall k. () => k -> * -> * -- | A Stream endpoint for a given method emits a stream of encoded values -- at a given Content-Type, delimited by a framing strategy. Stream -- endpoints always return response code 200 on success. Type synonyms -- are provided for standard methods. data Stream (method :: k1) (status :: Nat) framing contentType a :: forall k1. () => k1 -> Nat -> * -> * -> * -> * type StreamGet = Stream GET 200 type StreamPost = Stream POST 200 -- | Stream endpoints may be implemented as producing a -- StreamGenerator -- a function that itself takes two emit -- functions -- the first to be used on the first value the stream emits, -- and the second to be used on all subsequent values (to allow -- interspersed framing strategies such as comma separation). newtype StreamGenerator a StreamGenerator :: a -> IO () -> a -> IO () -> IO () -> StreamGenerator a [getStreamGenerator] :: StreamGenerator a -> a -> IO () -> a -> IO () -> IO () -- | ToStreamGenerator is intended to be implemented for types such as -- Conduit, Pipe, etc. By implementing this class, all such streaming -- abstractions can be used directly as endpoints. class ToStreamGenerator a b | a -> b toStreamGenerator :: ToStreamGenerator a b => a -> StreamGenerator b -- | Clients reading from streaming endpoints can be implemented as -- producing a ResultStream that captures the setup, takedown, -- and incremental logic for a read, being an IO continuation that takes -- a producer of Just either values or errors that terminates with a -- Nothing. newtype ResultStream a ResultStream :: forall b. () => IO Maybe Either String a -> IO b -> IO b -> ResultStream a -- | BuildFromStream is intended to be implemented for types such as -- Conduit, Pipe, etc. By implementing this class, all such streaming -- abstractions can be used directly on the client side for talking to -- streaming endpoints. class BuildFromStream a b buildFromStream :: BuildFromStream a b => ResultStream a -> b -- | The FramingRender class provides the logic for emitting a framing -- strategy. The strategy emits a header, followed by boundary-delimited -- data, and finally a termination character. For many strategies, some -- of these will just be empty bytestrings. class FramingRender (strategy :: k) (a :: k1) header :: FramingRender strategy a => Proxy strategy -> Proxy a -> ByteString boundary :: FramingRender strategy a => Proxy strategy -> Proxy a -> BoundaryStrategy trailer :: FramingRender strategy a => Proxy strategy -> Proxy a -> ByteString -- | The bracketing strategy generates things to precede and follow the -- content, as with netstrings. The intersperse strategy inserts -- seperators between things, as with newline framing. Finally, the -- general strategy performs an arbitrary rewrite on the content, to -- allow escaping rules and such. data BoundaryStrategy BoundaryStrategyBracket :: ByteString -> (ByteString, ByteString) -> BoundaryStrategy BoundaryStrategyIntersperse :: ByteString -> BoundaryStrategy BoundaryStrategyGeneral :: ByteString -> ByteString -> BoundaryStrategy -- | A type of parser that can never fail, and has different parsing -- strategies (incremental, or EOF) depending if more input can be sent. -- The incremental parser should return Nothing if it would like -- to be sent a longer ByteString. If it returns a value, it also returns -- the remainder following that value. data ByteStringParser a ByteStringParser :: ByteString -> Maybe (a, ByteString) -> ByteString -> (a, ByteString) -> ByteStringParser a [parseIncremental] :: ByteStringParser a -> ByteString -> Maybe (a, ByteString) [parseEOF] :: ByteStringParser a -> ByteString -> (a, ByteString) -- | The FramingUnrender class provides the logic for parsing a framing -- strategy. The outer ByteStringParser strips the header from a -- stream of bytes, and yields a parser that can handle the remainder, -- stepwise. Each frame may be a ByteString, or a String indicating the -- error state for that frame. Such states are per-frame, so that -- protocols that can resume after errors are able to do so. Eventually -- this returns an empty ByteString to indicate termination. class FramingUnrender (strategy :: k) (a :: k1) unrenderFrames :: FramingUnrender strategy a => Proxy strategy -> Proxy a -> ByteStringParser ByteStringParser Either String ByteString -- | A framing strategy that does not do any framing at all, it just passes -- the input data This will be used most of the time with binary data, -- such as files data NoFraming -- | A simple framing strategy that has no header or termination, and -- inserts a newline character between each frame. This assumes that it -- is used with a Content-Type that encodes without newlines (e.g. JSON). data NewlineFraming -- | The netstring framing strategy as defined by djb: -- http://cr.yp.to/proto/netstrings.txt data NetstringFraming -- | Deliberately do not add a header to a value. -- --
--   >>> let example1 = noHeader "hi" :: Headers '[Header "someheader" Int] String
--   
--   >>> getHeaders example1
--   []
--   
noHeader :: AddHeader h v orig new => orig -> new -- | addHeader adds a header to a response. Note that it changes -- the type of the value in the following ways: -- --
    --
  1. A simple value is wrapped in "Headers '[hdr]":
  2. --
-- --
--   >>> let example1 = addHeader 5 "hi" :: Headers '[Header "someheader" Int] String;
--   
--   >>> getHeaders example1
--   [("someheader","5")]
--   
-- --
    --
  1. A value that already has a header has its new header *prepended* -- to the existing list:
  2. --
-- --
--   >>> let example1 = addHeader 5 "hi" :: Headers '[Header "someheader" Int] String;
--   
--   >>> let example2 = addHeader True example1 :: Headers '[Header "1st" Bool, Header "someheader" Int] String
--   
--   >>> getHeaders example2
--   [("1st","true"),("someheader","5")]
--   
-- -- Note that while in your handlers type annotations are not required, -- since the type can be inferred from the API type, in other cases you -- may find yourself needing to add annotations. addHeader :: AddHeader h v orig new => v -> orig -> new -- | Response Header objects. You should never need to construct one -- directly. Instead, use addOptionalHeader. data Headers (ls :: [*]) a Headers :: a -> HList ls -> Headers a -- | The underlying value of a Headers [getResponse] :: Headers a -> a -- | HList of headers. [getHeadersHList] :: Headers a -> HList ls data ResponseHeader (sym :: Symbol) a Header :: a -> ResponseHeader a MissingHeader :: ResponseHeader a UndecodableHeader :: ByteString -> ResponseHeader a data HList (a :: [*]) [HNil] :: HList ([] :: [*]) [HCons] :: HList Header h x : xs class BuildHeadersTo (hs :: [*]) -- | Note: if there are multiple occurences of a header in the argument, -- the values are interspersed with commas before deserialization (see -- RFC2616 Sec 4.2) buildHeadersTo :: BuildHeadersTo hs => [Header] -> HList hs class GetHeaders ls getHeaders :: GetHeaders ls => ls -> [Header] class AddHeader (h :: Symbol) v orig new | h v orig -> new, new -> h, new -> v, new -> orig -- | Extract the request body as a value of type a. -- -- Example: -- --
--   >>> -- POST /books
--   
--   >>> type MyApi = "books" :> ReqBody '[JSON] Book :> Post '[JSON] Book
--   
type ReqBody = ReqBody' Required : Strict : ([] :: [*]) -- | Note: ReqBody' is always Required. data ReqBody' (mods :: [*]) (contentTypes :: [*]) a -- | Provides access to the host or IP address from which the HTTP request -- was sent. data RemoteHost -- | Endpoint for plugging in your own Wai Applications. -- -- The given Application will get the request as received by the -- server, potentially with a modified (stripped) pathInfo if -- the Application is being routed with :>. -- -- In addition to just letting you plug in your existing WAI -- Applications, this can also be used with -- serveDirectory to serve static files stored in a particular -- directory on your filesystem data Raw -- | Lookup the value associated to the sym query string parameter -- and try to extract it as a value of type a. -- -- Example: -- --
--   >>> -- /books?author=<author name>
--   
--   >>> type MyApi = "books" :> QueryParam "author" Text :> Get '[JSON] [Book]
--   
type QueryParam = QueryParam' Optional : Strict : ([] :: [*]) -- | QueryParam which can be Required, Lenient, or -- modified otherwise. data QueryParam' (mods :: [*]) (sym :: Symbol) a -- | Lookup the values associated to the sym query string -- parameter and try to extract it as a value of type [a]. This -- is typically meant to support query string parameters of the form -- param[]=val1&param[]=val2 and so on. Note that servant -- doesn't actually require the []s and will fetch the values -- just fine with param=val1&param=val2, too. -- -- Example: -- --
--   >>> -- /books?authors[]=<author1>&authors[]=<author2>&...
--   
--   >>> type MyApi = "books" :> QueryParams "authors" Text :> Get '[JSON] [Book]
--   
data QueryParams (sym :: Symbol) a -- | Lookup a potentially value-less query string parameter with boolean -- semantics. If the param sym is there without any value, or if -- it's there with value "true" or "1", it's interpreted as True. -- Otherwise, it's interpreted as False. -- -- Example: -- --
--   >>> -- /books?published
--   
--   >>> type MyApi = "books" :> QueryFlag "published" :> Get '[JSON] [Book]
--   
data QueryFlag (sym :: Symbol) -- | Extract the given header's value as a value of type a. I.e. -- header sent by client, parsed by server. -- -- Example: -- --
--   >>> newtype Referer = Referer Text deriving (Eq, Show)
--   
--   >>> 
--   
--   >>> -- GET /view-my-referer
--   
--   >>> type MyApi = "view-my-referer" :> Header "from" Referer :> Get '[JSON] Referer
--   
type Header = (Header' Optional : Strict : ([] :: [*]) :: Symbol -> k -> *) data Header' (mods :: [*]) (sym :: Symbol) (a :: k) :: forall k. () => [*] -> Symbol -> k -> * -- | Required argument. Not wrapped. data Required -- | Optional argument. Wrapped in Maybe. data Optional -- | Leniently parsed argument, i.e. parsing never fail. Wrapped in -- Either Text. data Lenient -- | Strictly parsed argument. Not wrapped. data Strict -- | Was this request made over an SSL connection? -- -- Note that this value will not tell you if the client originally made -- this request over SSL, but rather whether the current connection is -- SSL. The distinction lies with reverse proxies. In many cases, the -- client will connect to a load balancer over SSL, but connect to the -- WAI handler without SSL. In such a case, the handlers would get -- NotSecure, but from a user perspective, there is a secure -- connection. data IsSecure -- | the connection to the server is secure (HTTPS) Secure :: IsSecure -- | the connection to the server is not secure (HTTP) NotSecure :: IsSecure -- | A generalized Authentication combinator. Use this if you have a -- non-standard authentication technique. -- -- NOTE: THIS API IS EXPERIMENTAL AND SUBJECT TO CHANGE. data AuthProtect (tag :: k) :: forall k. () => k -> * -- | An empty API: one which serves nothing. Morally speaking, this should -- be the unit of :<|>. Implementors of interpretations of -- API types should treat EmptyAPI as close to the unit as -- possible. data EmptyAPI EmptyAPI :: EmptyAPI -- | Add a short summary for (part of) API. -- -- Example: -- --
--   >>> type MyApi = Summary "Get book by ISBN." :> "books" :> Capture "isbn" Text :> Get '[JSON] Book
--   
data Summary (sym :: Symbol) -- | Add more verbose description for (part of) API. -- -- Example: -- --
--   >>> :{
--   type MyApi = Description
--    "This comment is visible in multiple Servant interpretations \
--    \and can be really long if necessary. \
--    \Haskell multiline support is not perfect \
--    \but it's still very readable."
--   :> Get '[JSON] Book
--   :}
--   
data Description (sym :: Symbol) data JSON data PlainText data FormUrlEncoded data OctetStream -- | Instances of Accept represent mimetypes. They are used for -- matching against the Accept HTTP header of the request, and -- for setting the Content-Type header of the response -- -- Example: -- --
--   >>> import Network.HTTP.Media ((//), (/:))
--   
--   >>> data HTML
--   
--   >>> :{
--   instance Accept HTML where
--      contentType _ = "text" // "html" /: ("charset", "utf-8")
--   :}
--   
class Accept (ctype :: k) contentType :: Accept ctype => Proxy ctype -> MediaType contentTypes :: Accept ctype => Proxy ctype -> NonEmpty MediaType -- | Instantiate this class to register a way of serializing a type based -- on the Accept header. -- -- Example: -- --
--   data MyContentType
--   
--   instance Accept MyContentType where
--      contentType _ = "example" // "prs.me.mine" /: ("charset", "utf-8")
--   
--   instance Show a => MimeRender MyContentType a where
--      mimeRender _ val = pack ("This is MINE! " ++ show val)
--   
--   type MyAPI = "path" :> Get '[MyContentType] Int
--   
class Accept ctype => MimeRender (ctype :: k) a mimeRender :: MimeRender ctype a => Proxy ctype -> a -> ByteString -- | Instantiate this class to register a way of deserializing a type based -- on the request's Content-Type header. -- --
--   >>> import Network.HTTP.Media hiding (Accept)
--   
--   >>> import qualified Data.ByteString.Lazy.Char8 as BSC
--   
--   >>> data MyContentType = MyContentType String
--   
-- --
--   >>> :{
--   instance Accept MyContentType where
--      contentType _ = "example" // "prs.me.mine" /: ("charset", "utf-8")
--   :}
--   
-- --
--   >>> :{
--   instance Read a => MimeUnrender MyContentType a where
--      mimeUnrender _ bs = case BSC.take 12 bs of
--        "MyContentType" -> return . read . BSC.unpack $ BSC.drop 12 bs
--        _ -> Left "didn't start with the magic incantation"
--   :}
--   
-- --
--   >>> type MyAPI = "path" :> ReqBody '[MyContentType] Int :> Get '[JSON] Int
--   
class Accept ctype => MimeUnrender (ctype :: k) a mimeUnrender :: MimeUnrender ctype a => Proxy ctype -> ByteString -> Either String a -- | Variant which is given the actual MediaType provided by the -- other party. -- -- In the most cases you don't want to branch based on the -- MediaType. See pr552 for a motivating example. mimeUnrenderWithType :: MimeUnrender ctype a => Proxy ctype -> MediaType -> ByteString -> Either String a -- | A type for responses without content-body. data NoContent NoContent :: NoContent -- | Capture a value from the request path under a certain type a. -- -- Example: -- --
--   >>> -- GET /books/:isbn
--   
--   >>> type MyApi = "books" :> Capture "isbn" Text :> Get '[JSON] Book
--   
type Capture = Capture' ([] :: [*]) -- | Capture which can be modified. For example with -- Description. data Capture' (mods :: [*]) (sym :: Symbol) a -- | Capture all remaining values from the request path under a certain -- type a. -- -- Example: -- --
--   >>> -- GET /src/*
--   
--   >>> type MyAPI = "src" :> CaptureAll "segments" Text :> Get '[JSON] SourceFile
--   
data CaptureAll (sym :: Symbol) a -- | Combinator for Basic Access Authentication. -- -- -- -- In Basic Auth, username and password are base64-encoded and -- transmitted via the Authorization header. Handshakes are not -- required, making it relatively efficient. data BasicAuth (realm :: Symbol) userData -- | A simple datatype to hold data required to decorate a request data BasicAuthData BasicAuthData :: !ByteString -> !ByteString -> BasicAuthData [basicAuthUsername] :: BasicAuthData -> !ByteString [basicAuthPassword] :: BasicAuthData -> !ByteString -- | Union of two APIs, first takes precedence in case of overlap. -- -- Example: -- --
--   >>> :{
--   type MyApi = "books" :> Get '[JSON] [Book] -- GET /books
--          :<|> "books" :> ReqBody '[JSON] Book :> Post '[JSON] () -- POST /books
--   :}
--   
data (:<|>) a b (:<|>) :: a -> b -> (:<|>) a b -- | A persistent store for values of arbitrary types. -- -- This variant is the simplest and creates keys in the IO monad. -- See the module Data.Vault.ST if you want to use it with the -- ST monad instead. type Vault = Vault RealWorld class SBoolI (b :: Bool) sbool :: SBoolI b => SBool b data SBool (b :: Bool) [STrue] :: SBool True [SFalse] :: SBool False -- | Same as serveDirectoryFileServer. It used to be the only file -- serving function in servant pre-0.10 and will be kept around for a few -- versions, but is deprecated. serveDirectory :: () => FilePath -> ServerT Raw m -- | Alias for staticApp. Lets you serve a directory with arbitrary -- StaticSettings. Useful when you want particular settings not -- covered by the four other variants. This is the most flexible method. serveDirectoryWith :: () => StaticSettings -> ServerT Raw m -- | Uses embeddedSettings. serveDirectoryEmbedded :: () => [(FilePath, ByteString)] -> ServerT Raw m -- | Same as serveDirectoryWebApp, but uses -- webAppSettingsWithLookup. serveDirectoryWebAppLookup :: () => ETagLookup -> FilePath -> ServerT Raw m -- | Same as serveDirectoryWebApp, but uses -- defaultFileServerSettings. serveDirectoryFileServer :: () => FilePath -> ServerT Raw m -- | Serve anything under the specified directory as a Raw endpoint. -- --
--   type MyApi = "static" :> Raw
--   
--   server :: Server MyApi
--   server = serveDirectoryWebApp "/var/www"
--   
-- -- would capture any request to /static/<something> and -- look for <something> under /var/www. -- -- It will do its best to guess the MIME type for that file, based on the -- extension, and send an appropriate Content-Type header if -- possible. -- -- If your goal is to serve HTML, CSS and Javascript files that use the -- rest of the API as a webapp backend, you will most likely not want the -- static files to be hidden behind a /static/ prefix. In that -- case, remember to put the serveDirectoryWebApp handler in the -- last position, because servant will try to match the handlers -- in order. -- -- Corresponds to the defaultWebAppSettings StaticSettings -- value. serveDirectoryWebApp :: () => FilePath -> ServerT Raw m -- | Variant of layout that takes an additional Context. layoutWithContext :: HasServer api context => Proxy api -> Context context -> Text -- | The function layout produces a textual description of the -- internal router layout for debugging purposes. Note that the router -- layout is determined just by the API, not by the handlers. -- -- Example: -- -- For the following API -- --
--   type API =
--          "a" :> "d" :> Get '[JSON] NoContent
--     :<|> "b" :> Capture "x" Int :> Get '[JSON] Bool
--     :<|> "c" :> Put '[JSON] Bool
--     :<|> "a" :> "e" :> Get '[JSON] Int
--     :<|> "b" :> Capture "x" Int :> Put '[JSON] Bool
--     :<|> Raw
--   
-- -- we get the following output: -- --
--   /
--   ├─ a/
--   │  ├─ d/
--   │  │  └─•
--   │  └─ e/
--   │     └─•
--   ├─ b/
--   │  └─ <capture>/
--   │     ├─•
--   │     ┆
--   │     └─•
--   ├─ c/
--   │  └─•
--   ┆
--   └─ <raw>
--   
-- -- Explanation of symbols: -- -- layout :: HasServer api ([] :: [*]) => Proxy api -> Text -- | Hoist server implementation. -- -- Sometimes our cherished Handler monad isn't quite the type -- you'd like for your handlers. Maybe you want to thread some -- configuration in a Reader monad. Or have your types ensure -- that your handlers don't do any IO. Use hoistServer (a -- successor of now deprecated enter). -- -- With hoistServer, you can provide a function, to convert any -- number of endpoints from one type constructor to another. For example -- -- Note: Server Raw can also be entered. It will -- be retagged. -- --
--   >>> import Control.Monad.Reader
--   
--   >>> type ReaderAPI = "ep1" :> Get '[JSON] Int :<|> "ep2" :> Get '[JSON] String :<|> Raw :<|> EmptyAPI
--   
--   >>> let readerApi = Proxy :: Proxy ReaderAPI
--   
--   >>> let readerServer = return 1797 :<|> ask :<|> Tagged (error "raw server") :<|> emptyServer :: ServerT ReaderAPI (Reader String)
--   
--   >>> let nt x = return (runReader x "hi")
--   
--   >>> let mainServer = hoistServer readerApi nt readerServer :: Server ReaderAPI
--   
hoistServer :: HasServer api ([] :: [*]) => Proxy api -> forall x. () => m x -> n x -> ServerT api m -> ServerT api n serveWithContext :: HasServer api context => Proxy api -> Context context -> Server api -> Application -- | serve allows you to implement an API and produce a wai -- Application. -- -- Example: -- --
--   type MyApi = "books" :> Get '[JSON] [Book] -- GET /books
--           :<|> "books" :> ReqBody Book :> Post '[JSON] Book -- POST /books
--   
--   server :: Server MyApi
--   server = listAllBooks :<|> postBook
--     where listAllBooks = ...
--           postBook book = ...
--   
--   myApi :: Proxy MyApi
--   myApi = Proxy
--   
--   app :: Application
--   app = serve myApi server
--   
--   main :: IO ()
--   main = Network.Wai.Handler.Warp.run 8080 app
--   
serve :: HasServer api ([] :: [*]) => Proxy api -> Server api -> Application -- | Server for EmptyAPI emptyServer :: () => ServerT EmptyAPI m class HasServer (api :: k) (context :: [*]) where { type family ServerT (api :: k) (m :: * -> *) :: *; } route :: HasServer api context => Proxy api -> Context context -> Delayed env Server api -> Router env hoistServerWithContext :: HasServer api context => Proxy api -> Proxy context -> forall x. () => m x -> n x -> ServerT api m -> ServerT api n type Server (api :: k) = ServerT api Handler -- | Singleton type representing a server that serves an empty API. data EmptyServer -- | servant-server's current implementation of basic authentication is not -- immune to certian kinds of timing attacks. Decoding payloads does not -- take a fixed amount of time. -- -- The result of authentication/authorization data BasicAuthResult usr Unauthorized :: BasicAuthResult usr BadPassword :: BasicAuthResult usr NoSuchUser :: BasicAuthResult usr Authorized :: usr -> BasicAuthResult usr -- | Datatype wrapping a function used to check authentication. newtype BasicAuthCheck usr BasicAuthCheck :: BasicAuthData -> IO BasicAuthResult usr -> BasicAuthCheck usr [unBasicAuthCheck] :: BasicAuthCheck usr -> BasicAuthData -> IO BasicAuthResult usr -- | Apply a transformation to the response of a Router. tweakResponse :: () => RouteResult Response -> RouteResult Response -> Router env -> Router env toApplication :: RoutingApplication -> Application runHandler :: () => Handler a -> IO Either ServantErr a runHandler' :: Handler a -> ExceptT ServantErr IO a -- | err505 HTTP Version not supported -- -- Example usage: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err505 { errBody = "I support HTTP/4.0 only." }
--   
err505 :: ServantErr -- | err504 Gateway Time-out -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err504 { errBody = "Backend foobar did not respond in 5 seconds." }
--   
err504 :: ServantErr -- | err503 Service Unavailable -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err503 { errBody = "We're rewriting in PHP." }
--   
err503 :: ServantErr -- | err502 Bad Gateway -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err502 { errBody = "Tried gateway foo, bar, and baz.  None responded." }
--   
err502 :: ServantErr -- | err501 Not Implemented -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err501 { errBody = "/v1/foo is not supported with quux in the request." }
--   
err501 :: ServantErr -- | err500 Internal Server Error -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err500 { errBody = "Exception in module A.B.C:55.  Have a great day!" }
--   
err500 :: ServantErr -- | err422 Unprocessable Entity -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err422 { errBody = "I understood your request, but can't process it." }
--   
err422 :: ServantErr -- | err418 Expectation Failed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err418 { errBody = "Apologies, this is not a webserver but a teapot." }
--   
err418 :: ServantErr -- | err417 Expectation Failed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err417 { errBody = "I found a quux in the request.  This isn't going to work." }
--   
err417 :: ServantErr -- | err416 Request range not satisfiable -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err416 { errBody = "Valid range is [0, 424242]." }
--   
err416 :: ServantErr -- | err415 Unsupported Media Type -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err415 { errBody = "Supported media types:  gif, png" }
--   
err415 :: ServantErr -- | err414 Request-URI Too Large -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err414 { errBody = "Maximum length is 64." }
--   
err414 :: ServantErr -- | err413 Request Entity Too Large -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err413 { errBody = "Request exceeded 64k." }
--   
err413 :: ServantErr -- | err412 Precondition Failed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err412 { errBody = "Precondition fail: x < 42 && y > 57" }
--   
err412 :: ServantErr -- | err411 Length Required -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err411
--   
err411 :: ServantErr -- | err410 Gone -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err410 { errBody = "I know it was here at some point, but.. I blame bad luck." }
--   
err410 :: ServantErr -- | err409 Conflict -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err409 { errBody = "Transaction conflicts with 59879cb56c7c159231eeacdd503d755f7e835f74" }
--   
err409 :: ServantErr -- | err407 Proxy Authentication Required -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err407
--   
err407 :: ServantErr -- | err406 Not Acceptable -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err406
--   
err406 :: ServantErr -- | err405 Method Not Allowed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err405 { errBody = "Your account privileges does not allow for this.  Please pay $$$." }
--   
err405 :: ServantErr -- | err404 Not Found -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err404 { errBody = "(╯°□°)╯︵ ┻━┻)." }
--   
err404 :: ServantErr -- | err403 Forbidden -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err403 { errBody = "Please login first." }
--   
err403 :: ServantErr -- | err402 Payment Required -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err402 { errBody = "You have 0 credits. Please give me $$$." }
--   
err402 :: ServantErr -- | err401 Unauthorized -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err401 { errBody = "Your credentials are invalid." }
--   
err401 :: ServantErr -- | err400 Bad Request -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err400 { errBody = "Your request makes no sense to me." }
--   
err400 :: ServantErr -- | err307 Temporary Redirect -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err307
--   
err307 :: ServantErr -- | err305 Use Proxy -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err305
--   
err305 :: ServantErr -- | err304 Not Modified -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err304
--   
err304 :: ServantErr -- | err303 See Other -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err303
--   
err303 :: ServantErr -- | err302 Found -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err302
--   
err302 :: ServantErr -- | err301 Moved Permanently -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err301
--   
err301 :: ServantErr -- | err300 Multiple Choices -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err300 { errBody = "I can't choose." }
--   
err300 :: ServantErr data ServantErr ServantErr :: Int -> String -> ByteString -> [Header] -> ServantErr [errHTTPCode] :: ServantErr -> Int [errReasonPhrase] :: ServantErr -> String [errBody] :: ServantErr -> ByteString [errHeaders] :: ServantErr -> [Header] -- | descendIntoNamedContext allows you to access -- NamedContexts. Usually you won't have to use it yourself but -- instead use a combinator like WithNamedContext. -- -- This is how descendIntoNamedContext works: -- --
--   >>> :set -XFlexibleContexts
--   
--   >>> let subContext = True :. EmptyContext
--   
--   >>> :type subContext
--   subContext :: Context '[Bool]
--   
--   >>> let parentContext = False :. (NamedContext subContext :: NamedContext "subContext" '[Bool]) :. EmptyContext
--   
--   >>> :type parentContext
--   parentContext :: Context '[Bool, NamedContext "subContext" '[Bool]]
--   
--   >>> descendIntoNamedContext (Proxy :: Proxy "subContext") parentContext :: Context '[Bool]
--   True :. EmptyContext
--   
descendIntoNamedContext :: HasContextEntry context NamedContext name subContext => Proxy name -> Context context -> Context subContext -- | Contexts are used to pass values to combinators. (They are -- not meant to be used to pass parameters to your handlers, i.e. -- they should not replace any custom ReaderT-monad-stack that -- you're using with hoistServer.) If you don't use combinators -- that require any context entries, you can just use serve as -- always. -- -- If you are using combinators that require a non-empty Context -- you have to use serveWithContext and pass it a Context -- that contains all the values your combinators need. A Context -- is essentially a heterogenous list and accessing the elements is being -- done by type (see getContextEntry). The parameter of the type -- Context is a type-level list reflecting the types of the -- contained context entries. To create a Context with entries, -- use the operator (:.): -- --
--   >>> :type True :. () :. EmptyContext
--   True :. () :. EmptyContext :: Context '[Bool, ()]
--   
data Context (contextTypes :: [*]) [EmptyContext] :: Context ([] :: [*]) [:.] :: Context x : xs -- | This class is used to access context entries in Contexts. -- getContextEntry returns the first value where the type matches: -- --
--   >>> getContextEntry (True :. False :. EmptyContext) :: Bool
--   True
--   
-- -- If the Context does not contain an entry of the requested type, -- you'll get an error: -- --
--   >>> getContextEntry (True :. False :. EmptyContext) :: String
--   ...
--   ...No instance for (HasContextEntry '[] [Char])
--   ...
--   
class HasContextEntry (context :: [*]) val getContextEntry :: HasContextEntry context val => Context context -> val -- | Normally context entries are accessed by their types. In case you need -- to have multiple values of the same type in your Context and -- need to access them, we provide NamedContext. You can think of -- it as sub-namespaces for Contexts. data NamedContext (name :: Symbol) (subContext :: [*]) NamedContext :: Context subContext -> NamedContext -- | The WAI application. -- -- Note that, since WAI 3.0, this type is structured in continuation -- passing style to allow for proper safe resource handling. This was -- handled in the past via other means (e.g., ResourceT). As a -- demonstration: -- --
--   app :: Application
--   app req respond = bracket_
--       (putStrLn "Allocating scarce resource")
--       (putStrLn "Cleaning up")
--       (respond $ responseLBS status200 [] "Hello World")
--   
type Application = Request -> Response -> IO ResponseReceived -> IO ResponseReceived -- | A Tagged s b value is a value b with an -- attached phantom type s. This can be used in place of the -- more traditional but less safe idiom of passing in an undefined value -- with the type, because unlike an (s -> b), a -- Tagged s b can't try to use the argument s as -- a real value. -- -- Moreover, you don't have to rely on the compiler to inline away the -- extra argument, because the newtype is "free" -- -- Tagged has kind k -> * -> * if the compiler -- supports PolyKinds, therefore there is an extra k -- showing in the instance haddocks that may cause confusion. newtype Tagged (s :: k) b :: forall k. () => k -> * -> * Tagged :: b -> Tagged b [unTagged] :: Tagged b -> b runMagicbaneHandler :: β -> RIO β α -> Handler α -- | Constructs a WAI application from an API definition, a Servant context -- (used for auth mainly), the app context and the actual action -- handlers. magicbaneApp :: forall β χ ψ. (HasServer χ ψ) => Proxy χ -> Context ψ -> β -> ServerT χ (RIO β) -> Application -- | The Reader+IO monad. This is different from a ReaderT because: -- -- data RIO env a -- | Provides logging via fast-logger in a Magicbane app context. module Magicbane.Logging type Formatter = TimedFastLogger -> CallStack -> LogSource -> LogLevel -> Utf8Builder -> IO () type ModLogger = LogFunc -- | Creates a logger module using a given formatting function. | Also -- returns the underlying TimedFastLogger for use outside of your -- Magicbane app (e.g. in some WAI middleware). newLogger :: LogType -> Formatter -> IO (TimedFastLogger, ModLogger) simpleFormatter :: Formatter -- | Logger Type. data LogType -- | No logging. LogNone :: LogType -- | Logging to stdout. BufSize is a buffer size for each -- capability. LogStdout :: BufSize -> LogType -- | Logging to stderr. BufSize is a buffer size for each -- capability. LogStderr :: BufSize -> LogType -- | Logging to a file. BufSize is a buffer size for each -- capability. LogFileNoRotate :: FilePath -> BufSize -> LogType -- | Logging to a file. BufSize is a buffer size for each -- capability. File rotation is done on-demand. LogFile :: FileLogSpec -> BufSize -> LogType -- | Logging with a log and flush action. run flush after log each message. LogCallback :: LogStr -> IO () -> IO () -> LogType -- | The default buffer size (4,096 bytes). defaultBufSize :: BufSize -- | Provides metrics via monad-metrics/EKG in a Magicbane app context. -- Also reexports Wai metrics middleware. module Magicbane.Metrics newtype ModMetrics ModMetrics :: Metrics -> ModMetrics forkMetricsServer :: ByteString -> Int -> IO Server -- | Creates a metrics module with a particular Store. The Store should -- come from the backend you want to use for storing the metrics. For -- development, a simple backend that shows metrics on a web page is -- ekg-wai, reexported here. newMetricsWith :: Store -> IO ModMetrics -- | Register a number of metrics related to garbage collector behavior. -- -- To enable GC statistics collection, either run your program with -- --
--   +RTS -T
--   
-- -- or compile it with -- --
--   -with-rtsopts=-T
--   
-- -- The runtime overhead of -T is very small so it's safe to -- always leave it enabled. -- -- Registered counters: -- -- -- -- Registered gauges: -- -- registerGcMetrics :: Store -> IO () -- | A mutable metric store. data Store -- | The metric store associated with the server. If you want to add metric -- to the default store created by forkServer you need to use this -- function to retrieve it. serverMetricStore :: Server -> Store -- | Set the Label to the Shown value of whatever you pass -- in. -- -- label' :: (MonadIO m, MonadMetrics m, Show a) => Text -> a -> m () -- | Set the Label to the given Text value. -- -- label :: (MonadIO m, MonadMetrics m) => Text -> Text -> m () -- | Record the time of executing the given action in seconds. Defers to -- timed'. -- -- timed :: (MonadIO m, MonadMetrics m, MonadMask m) => Text -> m a -> m a -- | Record the time taken to perform the action, under several names at -- once. The number is stored in a Distribution and is converted -- to the specified Resolution. -- -- This is useful to store the same durations data sectioned by different -- criteria, e.g.: -- --
--   timedList Seconds ["request.byUser." <> userName, "request.byType." <> requestType] $ do
--       ...
--   
-- -- So you will have "request.byUser.someuser" storing duration -- distribution for requests of user "someuser" of any type; and -- "request.byType.sometype" storing duration distribution for -- requests of type "sometype" from any user. timedList :: (MonadIO m, MonadMetrics m, MonadMask m) => Resolution -> [Text] -> m a -> m a -- | Record the time taken to perform the named action. The number is -- stored in a Distribution and is converted to the specified -- Resolution. -- -- timed' :: (MonadIO m, MonadMetrics m, MonadMask m) => Resolution -> Text -> m a -> m a -- | A type specialized version of gauge' to avoid ambiguous types. -- -- gauge :: (MonadIO m, MonadMetrics m) => Text -> Int -> m () -- | Set the value of the named Gauge. -- -- gauge' :: (MonadIO m, MonadMetrics m, Integral int) => Text -> int -> m () -- | Add the value to the named Distribution. -- -- distribution :: (MonadIO m, MonadMetrics m) => Text -> Double -> m () -- | A type specialized version of counter' to avoid ambiguous type -- errors. -- -- counter :: (MonadIO m, MonadMetrics m) => Text -> Int -> m () -- | Adds the value to the named Counter. -- -- counter' :: (MonadIO m, MonadMetrics m, Integral int) => Text -> int -> m () -- | Increment the named counter by 1. -- -- increment :: (MonadIO m, MonadMetrics m) => Text -> m () -- | A type can be an instance of MonadMetrics if it can provide a -- Metrics somehow. Commonly, this will be implemented as a -- ReaderT where some field in the environment is the -- Metrics data. -- -- class Monad m => MonadMetrics (m :: * -> *) getMetrics :: MonadMetrics m => m Metrics -- | A lens into the Store provided by the Metrics. -- -- metricsStore :: Lens' Metrics Store -- | A lens into the Labels provided by the Metrics. -- -- metricsLabels :: Lens' Metrics IORef HashMap Text Label -- | A lens into the Gauges provided by the Metrics. -- -- metricsGauges :: Lens' Metrics IORef HashMap Text Gauge -- | A lens into the Counters provided by the Metrics. -- -- metricsCounters :: Lens' Metrics IORef HashMap Text Counter -- | A container for metrics used by the MonadMetrics class. -- -- data Metrics -- | A type representing the resolution of time to use for the -- timed metric. -- -- data Resolution Nanoseconds :: Resolution Microseconds :: Resolution Milliseconds :: Resolution Seconds :: Resolution Minutes :: Resolution Hours :: Resolution Days :: Resolution -- | Create a middleware to be added to a WAI-based webserver. metrics :: WaiMetrics -> Middleware -- | Register in EKG a number of metrics related to web server activity -- with a namespace. -- -- registerNamedWaiMetrics :: Text -> Store -> IO WaiMetrics -- | Register in EKG a number of metrics related to web server activity -- using empty namespace. -- -- registerWaiMetrics :: Store -> IO WaiMetrics -- | The metrics to feed in WAI and register in EKG. data WaiMetrics WaiMetrics :: Counter -> Distribution -> Counter -> Counter -> Counter -> Counter -> Counter -> WaiMetrics [requestCounter] :: WaiMetrics -> Counter [latencyDistribution] :: WaiMetrics -> Distribution [statusCode100Counter] :: WaiMetrics -> Counter [statusCode200Counter] :: WaiMetrics -> Counter [statusCode300Counter] :: WaiMetrics -> Counter [statusCode400Counter] :: WaiMetrics -> Counter [statusCode500Counter] :: WaiMetrics -> Counter -- | Various useful functions and type definitions. module Magicbane.Util type Host = Header "Host" Text type Form = ReqBody '[FormUrlEncoded] [(Text, Text)] type HTTPLink = Link type WithLink α = (Headers '[Header "Link" [HTTPLink]] α) hPutStrLn :: MonadIO μ => Handle -> String -> μ () -- | Merges two JSON objects recursively. When the values are not objects, -- just returns the left one. mergeVal :: Value -> Value -> Value -- | Encodes key-value data as application/x-www-form-urlencoded. writeForm :: (ConvertibleStrings α Text, ConvertibleStrings β Text, ConvertibleStrings ByteString γ) => [(α, β)] -> γ -- | Decodes key-value data from application/x-www-form-urlencoded. readForm :: (ConvertibleStrings Text α, ConvertibleStrings Text β, ConvertibleStrings γ ByteString) => γ -> Maybe [(α, β)] -- | Reads a Servant incoming form as a list of key-value pairs (for use in -- FromForm instances). formList :: Form -> [(Text, Text)] -- | Converts a flat key-value form with keys in typical nesting syntax -- (e.g. "one[two][three]") to an Aeson Value with nesting (for use in -- FromForm instances). formToObject :: [(Text, Text)] -> Value formKey :: Parser [Text] -- | Parses any string into a URI. parseUri :: ConvertibleStrings α String => α -> URI -- | Prepares text for inclusion in a URL. -- --
--   >>> :set -XOverloadedStrings
--   
--   >>> slugify "Hello & World!"
--   "hello-and-world"
--   
slugify :: Text -> Text -- | Creates a simple text/plain ServantErr. errText :: ServantErr -> ByteString -> ServantErr -- | Creates and throws a simple text/plain ServantErr. throwErrText :: MonadThrow μ => ServantErr -> ByteString -> μ α -- | Provides an HTTP(S) client via http-client(-tls) in a Magicbane app -- context. Also provides a simple composable interface for making -- arbitrary requests, based on http-client-conduit. That lets you plug -- stream parsers (e.g. html-conduit: 'performWithFn (.| sinkDoc)') -- directly into the reading of the response body. module Magicbane.HTTPClient type MonadHTTP ψ μ = (HasHttpManager ψ, MonadReader ψ μ, MonadUnliftIO μ) newtype ModHttpClient ModHttpClient :: Manager -> ModHttpClient newHttpClient :: IO ModHttpClient runHTTP :: ExceptT ε μ α -> μ (Either ε α) -- | Creates a request from a URI. reqU :: (MonadHTTP ψ μ) => URI -> ExceptT Text μ Request -- | Creates a request from a string of any type, parsing it into a URI. reqS :: (MonadHTTP ψ μ, ConvertibleStrings σ String) => σ -> ExceptT Text μ Request -- | Configures the request to not throw errors on error status codes. anyStatus :: (MonadHTTP ψ μ) => Request -> ExceptT Text μ Request -- | Sets a x-www-form-urlencoded form as the request body (also sets the -- content-type). postForm :: (MonadHTTP ψ μ) => [(Text, Text)] -> Request -> ExceptT Text μ Request -- | Sets a JSON value as the request body (via ToJSON; also sets the -- content-type). postJson :: (MonadHTTP ψ μ, ToJSON α) => α -> Request -> ExceptT Text μ Request -- | Performs the request, using a given function to read the body. This is -- what all other performWith functions are based on. performWithFn :: (MonadHTTP ψ μ, MonadCatch μ) => (ConduitM ι ByteString μ () -> ConduitT () Void μ ρ) -> Request -> ExceptT Text μ (Response ρ) -- | Performs the request, ignoring the body. performWithVoid :: (MonadHTTP ψ μ, MonadCatch μ) => Request -> ExceptT Text μ (Response ()) -- | Performs the request, reading the body into a lazy ByteString. performWithBytes :: (MonadHTTP ψ μ, MonadCatch μ) => Request -> ExceptT Text μ (Response ByteString) -- | Add headers to the request, preserving any existing headers not -- specified in the new set. applyHeaders :: RequestHeaders -> Request -> Request -- | Remove listed headers from the request. removeHeaders :: [HeaderName] -> Request -> Request -- | A monad transformer that adds exceptions to other monads. -- -- ExceptT constructs a monad parameterized over two things: -- -- -- -- The return function yields a computation that produces the -- given value, while >>= sequences two subcomputations, -- exiting on the first exception. newtype ExceptT e (m :: * -> *) a ExceptT :: m Either e a -> ExceptT e a -- | Monads which allow their actions to be run in IO. -- -- While MonadIO allows an IO action to be lifted into -- another monad, this class captures the opposite concept: allowing you -- to capture the monadic context. Note that, in order to meet the laws -- given below, the intuition is that a monad must have no monadic state, -- but may have monadic context. This essentially limits -- MonadUnliftIO to ReaderT and IdentityT -- transformers on top of IO. -- -- Laws. For any value u returned by askUnliftIO, it must -- meet the monad transformer laws as reformulated for -- MonadUnliftIO: -- -- -- -- The third is a currently nameless law which ensures that the current -- context is preserved. -- -- -- -- If you have a name for this, please submit it in a pull request for -- great glory. class MonadIO m => MonadUnliftIO (m :: * -> *) -- | The inverse of ExceptT. runExceptT :: () => ExceptT e m a -> m Either e a -- | A class for monads which allow exceptions to be caught, in particular -- exceptions which were thrown by throwM. -- -- Instances should obey the following law: -- --
--   catch (throwM e) f = f e
--   
-- -- Note that the ability to catch an exception does not guarantee -- that we can deal with all possible exit points from a computation. -- Some monads, such as continuation-based stacks, allow for more than -- just a success/failure strategy, and therefore catch -- cannot be used by those monads to properly implement a function -- such as finally. For more information, see MonadMask. class MonadThrow m => MonadCatch (m :: * -> *) -- | Represents a general universal resource identifier using its component -- parts. -- -- For example, for the URI -- --
--   foo://anonymous@www.haskell.org:42/ghc?query#frag
--   
-- -- the components are: data URI URI :: String -> Maybe URIAuth -> String -> String -> String -> URI -- |
--   foo:
--   
[uriScheme] :: URI -> String -- |
--   //anonymous@www.haskell.org:42
--   
[uriAuthority] :: URI -> Maybe URIAuth -- |
--   /ghc
--   
[uriPath] :: URI -> String -- |
--   ?query
--   
[uriQuery] :: URI -> String -- |
--   #frag
--   
[uriFragment] :: URI -> String -- | Use the default response timeout -- -- When used on a Request, means: use the manager's timeout value -- -- When used on a ManagerSettings, means: default to 30 seconds responseTimeoutDefault :: ResponseTimeout -- | Do not have a response timeout responseTimeoutNone :: ResponseTimeout -- | Specify a response timeout in microseconds responseTimeoutMicro :: Int -> ResponseTimeout -- | Set the proxy override value, for both HTTP (insecure) and HTTPS -- (insecure) connections. -- -- Since 0.4.7 managerSetProxy :: ProxyOverride -> ManagerSettings -> ManagerSettings -- | Set the proxy override value, only for HTTPS (secure) connections. -- -- Since 0.4.7 managerSetSecureProxy :: ProxyOverride -> ManagerSettings -> ManagerSettings -- | Set the proxy override value, only for HTTP (insecure) connections. -- -- Since 0.4.7 managerSetInsecureProxy :: ProxyOverride -> ManagerSettings -> ManagerSettings -- | A variant of withResponse which keeps a history of all -- redirects performed in the interim, together with the first 1024 bytes -- of their response bodies. -- -- Since 0.4.1 withResponseHistory :: () => Request -> Manager -> HistoriedResponse BodyReader -> IO a -> IO a -- | A variant of responseOpen which keeps a history of all -- redirects performed in the interim, together with the first 1024 bytes -- of their response bodies. -- -- Since 0.4.1 responseOpenHistory :: Request -> Manager -> IO HistoriedResponse BodyReader -- | A datatype holding information on redirected requests and the final -- response. -- -- Since 0.4.1 data HistoriedResponse body -- | Perform an action using a Connection acquired from the given -- Manager. -- -- You should use this only when you have to read and write interactively -- through the connection (e.g. connection by the WebSocket protocol). withConnection :: () => Request -> Manager -> Connection -> IO a -> IO a -- | Close any open resources associated with the given Response. -- In general, this will either close an active Connection or -- return it to the Manager to be reused. -- -- Since 0.1.0 responseClose :: () => Response a -> IO () -- | The most low-level function for initiating an HTTP request. -- -- The first argument to this function gives a full specification on the -- request: the host to connect to, whether to use SSL, headers, etc. -- Please see Request for full details. The second argument -- specifies which Manager should be used. -- -- This function then returns a Response with a BodyReader. -- The Response contains the status code and headers that were -- sent back to us, and the BodyReader contains the body of the -- request. Note that this BodyReader allows you to have fully -- interleaved IO actions during your HTTP download, making it possible -- to download very large responses in constant memory. -- -- An important note: the response body returned by this function -- represents a live HTTP connection. As such, if you do not use the -- response body, an open socket will be retained indefinitely. You must -- be certain to call responseClose on this response to free up -- resources. -- -- This function automatically performs any necessary redirects, as -- specified by the redirectCount setting. -- -- When implementing a (reverse) proxy using this function or relating -- functions, it's wise to remove Transfer-Encoding:, Content-Length:, -- Content-Encoding: and Accept-Encoding: from request and response -- headers to be relayed. -- -- Since 0.1.0 responseOpen :: Request -> Manager -> IO Response BodyReader -- | A convenient wrapper around withResponse which ignores the -- response body. This is useful, for example, when performing a HEAD -- request. -- -- Since 0.3.2 httpNoBody :: Request -> Manager -> IO Response () -- | A convenience wrapper around withResponse which reads in the -- entire response body and immediately closes the connection. Note that -- this function performs fully strict I/O, and only uses a lazy -- ByteString in its response for memory efficiency. If you are -- anticipating a large response body, you are encouraged to use -- withResponse and brRead instead. -- -- Since 0.1.0 httpLbs :: Request -> Manager -> IO Response ByteString -- | Perform a Request using a connection acquired from the given -- Manager, and then provide the Response to the given -- function. This function is fully exception safe, guaranteeing that the -- response will be closed when the inner function exits. It is defined -- as: -- --
--   withResponse req man f = bracket (responseOpen req man) responseClose f
--   
-- -- It is recommended that you use this function in place of explicit -- calls to responseOpen and responseClose. -- -- You will need to use functions such as brRead to consume the -- response body. -- -- Since 0.1.0 withResponse :: () => Request -> Manager -> Response BodyReader -> IO a -> IO a -- | Turn a SetCookie into a Cookie, if it is valid generateCookie :: SetCookie -> Request -> UTCTime -> Bool -> Maybe Cookie -- | Insert a cookie created by generateCookie into the cookie jar (or not -- if it shouldn't be allowed in) insertCheckedCookie :: Cookie -> CookieJar -> Bool -> CookieJar -- | This corresponds to the algorithm described in Section 5.3 "Storage -- Model" This function consists of calling generateCookie -- followed by insertCheckedCookie. Use this function if you plan -- to do both in a row. generateCookie and -- insertCheckedCookie are only provided for more fine-grained -- control. receiveSetCookie :: SetCookie -> Request -> UTCTime -> Bool -> CookieJar -> CookieJar -- | This applies receiveSetCookie to a given Response updateCookieJar :: () => Response a -> Request -> UTCTime -> CookieJar -> (CookieJar, Response a) -- | This corresponds to the algorithm described in Section 5.4 "The Cookie -- Header" computeCookieString :: Request -> CookieJar -> UTCTime -> Bool -> (ByteString, CookieJar) -- | This applies the computeCookieString to a given Request insertCookiesIntoRequest :: Request -> CookieJar -> UTCTime -> (Request, CookieJar) -- | This corresponds to the eviction algorithm described in Section 5.3 -- "Storage Model" evictExpiredCookies :: CookieJar -> UTCTime -> CookieJar removeExistingCookieFromCookieJar :: Cookie -> CookieJar -> (Maybe Cookie, CookieJar) destroyCookieJar :: CookieJar -> [Cookie] createCookieJar :: [Cookie] -> CookieJar -- | This corresponds to the subcomponent algorithm entitled "Path-Match" -- detailed in section 5.1.4 pathMatches :: ByteString -> ByteString -> Bool -- | This corresponds to the subcomponent algorithm entitled "Paths" -- detailed in section 5.1.4 defaultPath :: Request -> ByteString -- | This corresponds to the subcomponent algorithm entitled "Domain -- Matching" detailed in section 5.1.3 domainMatches :: ByteString -> ByteString -> Bool isIpAddress :: ByteString -> Bool -- | The default proxy settings for a manager. In particular: if the -- http_proxy (or https_proxy) environment variable is -- set, use it. Otherwise, use the values in the Request. -- -- Since 0.4.7 defaultProxy :: ProxyOverride -- | Same as proxyEnvironment, but instead of default environment -- variable names, allows you to set your own name. -- -- Since 0.4.7 proxyEnvironmentNamed :: Text -> Maybe Proxy -> ProxyOverride -- | Get the proxy settings from the default environment variable -- (http_proxy for insecure, https_proxy for secure). -- If no variable is set, then fall back to the given value. -- Nothing is equivalent to noProxy, Just is -- equivalent to useProxy. -- -- Since 0.4.7 proxyEnvironment :: Maybe Proxy -> ProxyOverride -- | Use the given proxy settings, regardless of the proxy value in the -- Request. -- -- Since 0.4.7 useProxy :: Proxy -> ProxyOverride -- | Never connect using a proxy, regardless of the proxy value in the -- Request. -- -- Since 0.4.7 noProxy :: ProxyOverride -- | Get the proxy settings from the Request itself. -- -- Since 0.4.7 proxyFromRequest :: ProxyOverride -- | Create, use and close a Manager. -- -- Since 0.2.1 withManager :: () => ManagerSettings -> Manager -> IO a -> IO a -- | Close all connections in a Manager. -- -- Note that this doesn't affect currently in-flight connections, meaning -- you can safely use it without hurting any queries you may have -- concurrently running. -- -- Since 0.1.0 closeManager :: Manager -> IO () -- | Create a Manager. The Manager will be shut down -- automatically via garbage collection. -- -- Creating a new Manager is a relatively expensive operation, you -- are advised to share a single Manager between requests instead. -- -- The first argument to this function is often -- defaultManagerSettings, though add-on libraries may provide a -- recommended replacement. -- -- Since 0.1.0 newManager :: ManagerSettings -> IO Manager -- | Default value for ManagerSettings. -- -- Note that this value does not have support for SSL/TLS. If you -- need to make any https connections, please use the http-client-tls -- package, which provides a tlsManagerSettings value. -- -- Since 0.1.0 defaultManagerSettings :: ManagerSettings -- | Same as rawConnectionModifySocket, but also takes in a chunk -- size. rawConnectionModifySocketSize :: Socket -> IO () -> IO Int -> Maybe HostAddress -> String -> Int -> IO Connection -- | A value for the managerRawConnection setting, but also allows -- you to modify the underlying Socket to set additional -- settings. For a motivating use case, see: -- https://github.com/snoyberg/http-client/issues/71. -- -- Since 0.3.8 rawConnectionModifySocket :: Socket -> IO () -> IO Maybe HostAddress -> String -> Int -> IO Connection -- | Send a file as the request body, while observing streaming progress -- via a PopObserver. Observations are made between reading and -- sending a chunk. -- -- It is expected that the file size does not change between calling -- observedStreamFile and making any requests using this request -- body. -- -- Since 0.4.9 observedStreamFile :: StreamFileStatus -> IO () -> FilePath -> IO RequestBody -- | Send a file as the request body. -- -- It is expected that the file size does not change between calling -- streamFile and making any requests using this request body. -- -- Since 0.4.9 streamFile :: FilePath -> IO RequestBody -- | Set the query string to the given key/value pairs. setQueryStringPartialEscape :: [(ByteString, [EscapeItem])] -> Request -> Request -- | Set the query string to the given key/value pairs. -- -- Since 0.3.6 setQueryString :: [(ByteString, Maybe ByteString)] -> Request -> Request -- | Modify the request so that non-2XX status codes generate a runtime -- StatusCodeException, by using throwErrorStatusCodes setRequestCheckStatus :: Request -> Request -- | Modify the request so that non-2XX status codes do not generate a -- runtime StatusCodeException. setRequestIgnoreStatus :: Request -> Request -- | Add url-encoded parameters to the Request. -- -- This sets a new requestBody, adds a content-type request header -- and changes the method to POST. -- -- Since 0.1.0 urlEncodedBody :: [(ByteString, ByteString)] -> Request -> Request -- | Add a Proxy-Authorization header (with the specified username and -- password) to the given Request. Ignore error handling: -- --
--   applyBasicProxyAuth "user" "pass" <$> parseRequest "http://example.org"
--   
-- -- Since 0.3.4 applyBasicProxyAuth :: ByteString -> ByteString -> Request -> Request -- | Add a Basic Auth header (with the specified user name and password) to -- the given Request. Ignore error handling: -- --
--   applyBasicAuth "user" "pass" $ parseRequest_ url
--   
-- -- NOTE: The function applyDigestAuth is provided by the -- http-client-tls package instead of this package due to extra -- dependencies. Please use that package if you need to use digest -- authentication. -- -- Since 0.1.0 applyBasicAuth :: ByteString -> ByteString -> Request -> Request -- | A default request value, a GET request of localhost/:80, with an empty -- request body. -- -- Note that the default checkResponse does nothing. defaultRequest :: Request -- | Extract a URI from the request. -- -- Since 0.1.0 getUri :: Request -> URI -- | Same as requestFromURI, but if the conversion would fail, -- throws an impure exception. requestFromURI_ :: URI -> Request -- | Convert a URI into a Request. -- -- This can fail if the given URI is not absolute, or if the -- URI scheme is not "http" or "https". In these -- cases the function will throw an error via MonadThrow. -- -- This function defaults some of the values in Request, such as -- setting method to GET and requestHeaders -- to []. -- -- A Request created by this function won't cause exceptions on -- non-2XX response status codes. requestFromURI :: MonadThrow m => URI -> m Request -- | Same as parseRequest, but parse errors cause an impure -- exception. Mostly useful for static strings which are known to be -- correctly formatted. parseRequest_ :: String -> Request -- | Convert a URL into a Request. -- -- This function defaults some of the values in Request, such as -- setting method to GET and requestHeaders -- to []. -- -- Since this function uses MonadThrow, the return monad can be -- anything that is an instance of MonadThrow, such as IO -- or Maybe. -- -- You can place the request method at the beginning of the URL separated -- by a space, e.g.: -- -- @@ parseRequest "POST http://httpbin.org/post" @@ -- -- Note that the request method must be provided as all capital letters. -- -- A Request created by this function won't cause exceptions on -- non-2XX response status codes. -- -- To create a request which throws on non-2XX status codes, see -- parseUrlThrow parseRequest :: MonadThrow m => String -> m Request -- | Throws a StatusCodeException wrapped in -- HttpExceptionRequest, if the response's status code indicates -- an error (if it isn't 2xx). This can be used to implement -- checkResponse. throwErrorStatusCodes :: MonadIO m => Request -> Response BodyReader -> m () -- | Same as parseRequest, except will throw an HttpException -- in the event of a non-2XX response. This uses -- throwErrorStatusCodes to implement checkResponse. parseUrlThrow :: MonadThrow m => String -> m Request -- | Deprecated synonym for parseUrlThrow. You probably want -- parseRequest or parseRequest_ instead. parseUrl :: MonadThrow m => String -> m Request -- | Strictly consume all remaining chunks of data from the stream. -- -- Since 0.1.0 brConsume :: BodyReader -> IO [ByteString] -- | Continuously call brRead, building up a lazy ByteString until a -- chunk is constructed that is at least as many bytes as requested. -- -- Since 0.4.20 brReadSome :: BodyReader -> Int -> IO ByteString -- | Get a single chunk of data from the response body, or an empty -- bytestring if no more data is available. -- -- Note that in order to consume the entire request body, you will need -- to repeatedly call this function until you receive an empty -- ByteString as a result. -- -- Since 0.1.0 brRead :: BodyReader -> IO ByteString -- | Create a new Connection from a Socket. socketConnection :: Socket -> Int -> IO Connection -- | Create a new Connection from a read, write, and close function. makeConnection :: IO ByteString -> ByteString -> IO () -> IO () -> IO Connection -- | An IO action that represents an incoming response body coming -- from the server. Data provided by this action has already been -- gunzipped and de-chunked, and respects any content-length headers -- present. -- -- The action gets a single chunk of data from the response body, or an -- empty bytestring if no more data is available. -- -- Since 0.4.0 type BodyReader = IO ByteString -- | An exception which may be generated by this library data HttpException -- | Most exceptions are specific to a Request. Inspect the -- HttpExceptionContent value for details on what occurred. HttpExceptionRequest :: Request -> HttpExceptionContent -> HttpException -- | A URL (first field) is invalid for a given reason (second argument). InvalidUrlException :: String -> String -> HttpException data HttpExceptionContent -- | Generated by the parseUrlThrow function when the server -- returns a non-2XX response status code. -- -- May include the beginning of the response body. StatusCodeException :: Response () -> ByteString -> HttpExceptionContent -- | The server responded with too many redirects for a request. -- -- Contains the list of encountered responses containing redirects in -- reverse chronological order; including last redirect, which triggered -- the exception and was not followed. TooManyRedirects :: [Response ByteString] -> HttpExceptionContent -- | Either too many headers, or too many total bytes in a single header, -- were returned by the server, and the memory exhaustion protection in -- this library has kicked in. OverlongHeaders :: HttpExceptionContent -- | The server took too long to return a response. This can be altered via -- responseTimeout or managerResponseTimeout. ResponseTimeout :: HttpExceptionContent -- | Attempting to connect to the server timed out. ConnectionTimeout :: HttpExceptionContent -- | An exception occurred when trying to connect to the server. ConnectionFailure :: SomeException -> HttpExceptionContent -- | The status line returned by the server could not be parsed. InvalidStatusLine :: ByteString -> HttpExceptionContent -- | The given response header line could not be parsed InvalidHeader :: ByteString -> HttpExceptionContent -- | An exception was raised by an underlying library when performing the -- request. Most often, this is caused by a failing socket action or a -- TLS exception. InternalException :: SomeException -> HttpExceptionContent -- | A non-200 status code was returned when trying to connect to the proxy -- server on the given host and port. ProxyConnectException :: ByteString -> Int -> Status -> HttpExceptionContent -- | No response data was received from the server at all. This exception -- may deserve special handling within the library, since it may indicate -- that a pipelining has been used, and a connection thought to be open -- was in fact closed. NoResponseDataReceived :: HttpExceptionContent -- | Exception thrown when using a Manager which does not have -- support for secure connections. Typically, you will want to use -- tlsManagerSettings from http-client-tls to overcome -- this. TlsNotSupported :: HttpExceptionContent -- | The request body provided did not match the expected size. -- -- Provides the expected and actual size. WrongRequestBodyStreamSize :: Word64 -> Word64 -> HttpExceptionContent -- | The returned response body is too short. Provides the expected size -- and actual size. ResponseBodyTooShort :: Word64 -> Word64 -> HttpExceptionContent -- | A chunked response body had invalid headers. InvalidChunkHeaders :: HttpExceptionContent -- | An incomplete set of response headers were returned. IncompleteHeaders :: HttpExceptionContent -- | The host we tried to connect to is invalid (e.g., an empty string). InvalidDestinationHost :: ByteString -> HttpExceptionContent -- | An exception was thrown when inflating a response body. HttpZlibException :: ZlibException -> HttpExceptionContent -- | Values in the proxy environment variable were invalid. Provides the -- environment variable name and its value. InvalidProxyEnvironmentVariable :: Text -> Text -> HttpExceptionContent -- | Attempted to use a Connection which was already closed ConnectionClosed :: HttpExceptionContent -- | Proxy settings are not valid (Windows specific currently) @since 0.5.7 InvalidProxySettings :: Text -> HttpExceptionContent data Cookie Cookie :: ByteString -> ByteString -> UTCTime -> ByteString -> ByteString -> UTCTime -> UTCTime -> Bool -> Bool -> Bool -> Bool -> Cookie [cookie_name] :: Cookie -> ByteString [cookie_value] :: Cookie -> ByteString [cookie_expiry_time] :: Cookie -> UTCTime [cookie_domain] :: Cookie -> ByteString [cookie_path] :: Cookie -> ByteString [cookie_creation_time] :: Cookie -> UTCTime [cookie_last_access_time] :: Cookie -> UTCTime [cookie_persistent] :: Cookie -> Bool [cookie_host_only] :: Cookie -> Bool [cookie_secure_only] :: Cookie -> Bool [cookie_http_only] :: Cookie -> Bool data CookieJar -- | The host name of the HTTP proxy. proxyHost :: Proxy -> ByteString -- | The port number of the HTTP proxy. proxyPort :: Proxy -> Int -- | When using one of the RequestBodyStream / -- RequestBodyStreamChunked constructors, you must ensure that the -- GivesPopper can be called multiple times. Usually this is not a -- problem. -- -- The RequestBodyStreamChunked will send a chunked request body. -- Note that not all servers support this. Only use -- RequestBodyStreamChunked if you know the server you're sending -- to supports chunked request bodies. -- -- Since 0.1.0 data RequestBody RequestBodyLBS :: ByteString -> RequestBody RequestBodyBS :: ByteString -> RequestBody RequestBodyBuilder :: Int64 -> Builder -> RequestBody RequestBodyStream :: Int64 -> GivesPopper () -> RequestBody RequestBodyStreamChunked :: GivesPopper () -> RequestBody -- | Allows creation of a RequestBody inside the IO -- monad, which is useful for making easier APIs (like -- setRequestBodyFile). RequestBodyIO :: IO RequestBody -> RequestBody -- | A function which generates successive chunks of a request body, -- provider a single empty bytestring when no more data is available. -- -- Since 0.1.0 type Popper = IO ByteString -- | A function which must be provided with a Popper. -- -- Since 0.1.0 type NeedsPopper a = Popper -> IO a -- | A function which will provide a Popper to a NeedsPopper. -- This seemingly convoluted structure allows for creation of request -- bodies which allocate scarce resources in an exception safe manner. -- -- Since 0.1.0 type GivesPopper a = NeedsPopper a -> IO a -- | All information on how to connect to a host and what should be sent in -- the HTTP request. -- -- If you simply wish to download from a URL, see parseRequest. -- -- The constructor for this data type is not exposed. Instead, you should -- use either the defaultRequest value, or parseRequest -- to construct from a URL, and then use the records below to make -- modifications. This approach allows http-client to add configuration -- options without breaking backwards compatibility. -- -- For example, to construct a POST request, you could do something like: -- --
--   initReq <- parseRequest "http://www.example.com/path"
--   let req = initReq
--               { method = "POST"
--               }
--   
-- -- For more information, please see -- http://www.yesodweb.com/book/settings-types. -- -- Since 0.1.0 data Request -- | How to deal with timing out a response data ResponseTimeout -- | A simple representation of the HTTP response. -- -- Since 0.1.0 data Response body -- | Settings for a Manager. Please use the -- defaultManagerSettings function and then modify individual -- settings. For more information, see -- http://www.yesodweb.com/book/settings-types. -- -- Since 0.1.0 data ManagerSettings -- | How the HTTP proxy server settings should be discovered. -- -- Since 0.4.7 data ProxyOverride -- | Keeps track of open connections for keep-alive. -- -- If possible, you should share a single Manager between multiple -- threads and requests. -- -- Since 0.1.0 data Manager class HasHttpManager a getHttpManager :: HasHttpManager a => a -> Manager -- | Status of streaming a request body from a file. -- -- Since 0.4.9 data StreamFileStatus StreamFileStatus :: Int64 -> Int64 -> Int -> StreamFileStatus [fileSize] :: StreamFileStatus -> Int64 [readSoFar] :: StreamFileStatus -> Int64 [thisChunkSize] :: StreamFileStatus -> Int fragment :: URI -> String query :: URI -> String path :: URI -> String authority :: URI -> String scheme :: URI -> String unreserved :: Char -> Bool reserved :: Char -> Bool escapeString :: String -> Char -> Bool -> String parseabsoluteURI :: String -> Maybe URI -- | Path segment normalization; cf. RFC3986 section 6.2.2.3 normalizePathSegments :: String -> String -- | Encoding normalization; cf. RFC3986 section 6.2.2.2 normalizeEscape :: String -> String -- | Case normalization; cf. RFC3986 section 6.2.2.1 NOTE: authority case -- normalization is not performed normalizeCase :: String -> String -- | Returns a new URI which represents the relative location of the -- first URI with respect to the second URI. Thus, the -- values supplied are expected to be absolute URIs, and the result -- returned may be a relative URI. -- -- Example: -- --
--   "http://example.com/Root/sub1/name2#frag"
--     `relativeFrom` "http://example.com/Root/sub2/name2#frag"
--     == "../sub1/name2#frag"
--   
-- -- There is no single correct implementation of this function, but any -- acceptable implementation must satisfy the following: -- --
--   (uabs `relativeFrom` ubase) `relativeTo` ubase == uabs
--   
-- -- For any valid absolute URI. (cf. -- http://lists.w3.org/Archives/Public/uri/2003Jan/0008.html -- http://lists.w3.org/Archives/Public/uri/2003Jan/0005.html) relativeFrom :: URI -> URI -> URI -- | Returns the segments of the path component. E.g., pathSegments -- $ parseURI "http://example.org/foo/bar/baz" == ["foo", -- "bar", "baz"] pathSegments :: URI -> [String] -- | Returns a new URI which represents the value of the first -- URI interpreted as relative to the second URI. -- -- Algorithm from RFC3986 [3], section 5.2 relativeTo :: URI -> URI -> URI -- | Returns a new URI which represents the value of the first -- URI interpreted as relative to the second URI. For -- example: -- --
--   "foo" `relativeTo` "http://bar.org/" = "http://bar.org/foo"
--   "http:foo" `nonStrictRelativeTo` "http://bar.org/" = "http://bar.org/foo"
--   
-- -- Algorithm from RFC3986 [3], section 5.2.2 nonStrictRelativeTo :: URI -> URI -> URI -- | Turns all instances of escaped characters in the string back into -- literal characters. unEscapeString :: String -> String -- | Can be used to make a string valid for use in a URI. escapeURIString :: Char -> Bool -> String -> String -- | Escape character if supplied predicate is not satisfied, otherwise -- return character as singleton string. escapeURIChar :: Char -> Bool -> Char -> String -- | Returns True if the character is allowed unescaped in a URI -- component. -- --
--   >>> escapeURIString isUnescapedInURIComponent "http://haskell.org:80?some_param=true&other_param=їґ"
--   "http%3A%2F%2Fhaskell.org%3A80%3Fsome_param%3Dtrue%26other_param%3D%D1%97%D2%91"
--   
isUnescapedInURIComponent :: Char -> Bool -- | Returns True if the character is allowed unescaped in a URI. -- --
--   >>> escapeURIString isUnescapedInURI "http://haskell.org:80?some_param=true&other_param=їґ"
--   "http://haskell.org:80?some_param=true&other_param=%D1%97%D2%91"
--   
isUnescapedInURI :: Char -> Bool -- | Returns True if the character is allowed in a URI. isAllowedInURI :: Char -> Bool -- | Turn a URI into a string. -- -- Uses a supplied function to map the userinfo part of the URI. -- -- The Show instance for URI uses a mapping that hides any password that -- may be present in the URI. Use this function with argument id -- to preserve the password in the formatted output. uriToString :: String -> String -> URI -> ShowS -- | Returns True if the character is an "unreserved" character in a -- URI. These characters do not need to be escaped in a URI. The only -- characters allowed in a URI are either "reserved", "unreserved", or an -- escape sequence (% followed by two hex digits). isUnreserved :: Char -> Bool -- | Returns True if the character is a "reserved" character in a -- URI. To include a literal instance of one of these characters in a -- component of a URI, it must be escaped. isReserved :: Char -> Bool uriIsRelative :: URI -> Bool uriIsAbsolute :: URI -> Bool -- | Test if string contains a valid IPv4 address isIPv4address :: String -> Bool -- | Test if string contains a valid IPv6 address isIPv6address :: String -> Bool -- | Test if string contains a valid absolute URI (an absolute URI without -- a fragment identifier). isAbsoluteURI :: String -> Bool -- | Test if string contains a valid relative URI (a relative URI with -- optional fragment identifier). isRelativeReference :: String -> Bool -- | Test if string contains a valid URI reference (an absolute or relative -- URI with optional fragment identifier). isURIReference :: String -> Bool -- | Test if string contains a valid URI (an absolute URI with optional -- fragment identifier). isURI :: String -> Bool -- | Parse an absolute URI to a URI value. Returns Nothing if -- the string is not a valid absolute URI. (an absolute URI without a -- fragment identifier). parseAbsoluteURI :: String -> Maybe URI -- | Parse a relative URI to a URI value. Returns Nothing if -- the string is not a valid relative URI. (a relative URI with optional -- fragment identifier). parseRelativeReference :: String -> Maybe URI -- | Parse a URI reference to a URI value. Returns Nothing if -- the string is not a valid URI reference. (an absolute or relative URI -- with optional fragment identifier). parseURIReference :: String -> Maybe URI -- | Turn a string containing a URI into a URI. Returns -- Nothing if the string is not a valid URI; (an absolute URI with -- optional fragment identifier). -- -- NOTE: this is different from the previous network.URI, whose -- parseURI function works like parseURIReference in this -- module. parseURI :: String -> Maybe URI -- | Blank URI nullURI :: URI -- | Type for authority value within a URI data URIAuth URIAuth :: String -> String -> String -> URIAuth -- |
--   anonymous@
--   
[uriUserInfo] :: URIAuth -> String -- |
--   www.haskell.org
--   
[uriRegName] :: URIAuth -> String -- |
--   :42
--   
[uriPort] :: URIAuth -> String -- | Orphan instances and utility functions for Data.Has, a typeclass for -- extracting values from a structure by type. module Magicbane.Has -- | Gets a value of any type from the context. askObj :: (Has β α, MonadReader α μ) => μ β -- | Gets a thing from a value of any type from the context. (Useful for -- configuration fields.) askOpt :: (Has β α, MonadReader α μ) => (β -> ψ) -> μ ψ instance Data.Has.Has Magicbane.HTTPClient.ModHttpClient α => Network.HTTP.Client.Types.HasHttpManager α instance Data.Has.Has Magicbane.Logging.ModLogger α => RIO.Prelude.Logger.HasLogFunc α instance (Data.Has.Has Magicbane.Metrics.ModMetrics α, GHC.Base.Monad μ, Control.Monad.Reader.Class.MonadReader α μ) => Control.Monad.Metrics.MonadMetrics μ -- | Utility functions and reexports for System.Envy, an environment -- variable config reader. module Magicbane.Config -- | Display all environment variables, for convenience showEnv :: IO () -- | Unset Environment using a value of class ToEnv unsetEnvironment' :: ToEnv a => a -> IO Either String () -- | Unset Environment from a ToEnv constrained type unsetEnvironment :: () => EnvList a -> IO Either String () -- | Set environment directly using a value of class ToEnv setEnvironment' :: ToEnv a => a -> IO Either String () -- | Set environment via a ToEnv constrained type setEnvironment :: () => EnvList a -> IO Either String () -- | Environment retrieval with failure info decodeEnv :: FromEnv a => IO Either String a -- | Smart constructor, environment creation helper. makeEnv :: () => [EnvVar] -> EnvList a -- | Meant for specifying a custom Option for environment retrieval -- --
--   instance FromEnv PGConfig where
--     fromEnv = gFromEnvCustom Option { dropPrefixCount = 8, customPrefix = "PG" }
--   
gFromEnvCustom :: (DefConfig a, Generic a, GFromEnv Rep a) => Option -> Parser a -- | Environment variable getter returning Maybe envMaybe :: Var a => String -> Parser Maybe a -- | Environment variable getter. Fails if the variable is not set or fails -- to parse. env :: Var a => String -> Parser a -- | For use with Generics, no FromEnv typeclass necessary -- --
--   getPgConfig :: IO (Either String ConnectInfo)
--   getPgConfig = runEnv $ gFromEnvCustom defOption
--   
runEnv :: () => Parser a -> IO Either String a -- | Parser Monad for environment variable retrieval newtype Parser a Parser :: ExceptT String IO a -> Parser a [runParser] :: Parser a -> ExceptT String IO a -- | FromEnv Typeclass w/ Generic default implementation class FromEnv a fromEnv :: FromEnv a => Parser a -- | Type class for objects which have a default configuration. class DefConfig a defConfig :: DefConfig a => a -- | For customizing environment variable generation data Option Option :: Int -> String -> Option -- | Applied first [dropPrefixCount] :: Option -> Int -- | Converted toUpper [customPrefix] :: Option -> String -- | Type class for objects which can be converted to a set of environment -- variable settings. class ToEnv a -- | Convert an object into a list of environment variable settings. toEnv :: ToEnv a => a -> EnvList a -- | List of environment variables. Captures a "phantom type" which allows -- the type checker to detect the proper implementation of toEnv to use. data EnvList a -- | Class for converting to / from an environment variable class Typeable a => Var a -- | Convert a value into an environment variable. toVar :: Var a => a -> String -- | Parse an environment variable. fromVar :: Var a => String -> Maybe a decodeEnvy :: FromEnv a => IO Maybe a -- | Reads an Envy configuration from the env variables and launches the -- given action if successful. (Does environment variable reading ever -- fail in practice? Probably not.) withEnvConfig :: FromEnv α => (α -> IO ()) -> IO () -- | Integrates the refinement types from the refined library with aeson. module Magicbane.Validation instance Data.Aeson.Types.ToJSON.ToJSON α => Data.Aeson.Types.ToJSON.ToJSON (Refined.Refined ρ α) instance (Data.Aeson.Types.FromJSON.FromJSON α, Refined.Predicate ρ α) => Data.Aeson.Types.FromJSON.FromJSON (Refined.Refined ρ α) -- | A Dropwizard-inspired web framework that integrates Servant, -- monad-metricsEKG, monad-loggerfast-logger, and other useful -- libraries to provide a smooth web service development experience. -- -- This module provides all the stuff you need for an application: - -- reexports from all the modules below, including orphan instances from -- Magicbane.Has - orphan instances for RIO - reexports from various -- utility packages - a basic example context for simple apps module Magicbane -- | If the first argument evaluates to True, then the result is the -- second argument. Otherwise an AssertionFailed exception is -- raised, containing a String with the source file and line -- number of the call to assert. -- -- Assertions can normally be turned on or off with a compiler flag (for -- GHC, assertions are normally on unless optimisation is turned on with -- -O or the -fignore-asserts option is given). When -- assertions are turned off, the first argument to assert is -- ignored, and the second argument is returned as the result. assert :: () => Bool -> a -> a -- | The class Typeable allows a concrete representation of a type -- to be calculated. class Typeable (a :: k) -- | Like decodeFileStrict' but returns an error message when -- decoding fails. eitherDecodeFileStrict' :: FromJSON a => FilePath -> IO Either String a -- | Like decodeStrict' but returns an error message when decoding -- fails. eitherDecodeStrict' :: FromJSON a => ByteString -> Either String a -- | Like decode' but returns an error message when decoding fails. eitherDecode' :: FromJSON a => ByteString -> Either String a -- | Like decodeFileStrict but returns an error message when -- decoding fails. eitherDecodeFileStrict :: FromJSON a => FilePath -> IO Either String a -- | Like decodeStrict but returns an error message when decoding -- fails. eitherDecodeStrict :: FromJSON a => ByteString -> Either String a -- | Like decode but returns an error message when decoding fails. eitherDecode :: FromJSON a => ByteString -> Either String a -- | Efficiently deserialize a JSON value from a file. If this fails due to -- incomplete or invalid input, Nothing is returned. -- -- The input file's content must consist solely of a JSON document, with -- no trailing data except for whitespace. -- -- This function parses and performs conversion immediately. See -- json' for details. decodeFileStrict' :: FromJSON a => FilePath -> IO Maybe a -- | Efficiently deserialize a JSON value from a strict ByteString. -- If this fails due to incomplete or invalid input, Nothing is -- returned. -- -- The input must consist solely of a JSON document, with no trailing -- data except for whitespace. -- -- This function parses and performs conversion immediately. See -- json' for details. decodeStrict' :: FromJSON a => ByteString -> Maybe a -- | Efficiently deserialize a JSON value from a lazy ByteString. If -- this fails due to incomplete or invalid input, Nothing is -- returned. -- -- The input must consist solely of a JSON document, with no trailing -- data except for whitespace. -- -- This function parses and performs conversion immediately. See -- json' for details. decode' :: FromJSON a => ByteString -> Maybe a -- | Efficiently deserialize a JSON value from a file. If this fails due to -- incomplete or invalid input, Nothing is returned. -- -- The input file's content must consist solely of a JSON document, with -- no trailing data except for whitespace. -- -- This function parses immediately, but defers conversion. See -- json for details. decodeFileStrict :: FromJSON a => FilePath -> IO Maybe a -- | Efficiently deserialize a JSON value from a strict ByteString. -- If this fails due to incomplete or invalid input, Nothing is -- returned. -- -- The input must consist solely of a JSON document, with no trailing -- data except for whitespace. -- -- This function parses immediately, but defers conversion. See -- json for details. decodeStrict :: FromJSON a => ByteString -> Maybe a -- | Efficiently deserialize a JSON value from a lazy ByteString. If -- this fails due to incomplete or invalid input, Nothing is -- returned. -- -- The input must consist solely of a JSON document, with no trailing -- data except for whitespace. -- -- This function parses immediately, but defers conversion. See -- json for details. decode :: FromJSON a => ByteString -> Maybe a -- | Efficiently serialize a JSON value as a lazy ByteString and -- write it to a file. encodeFile :: ToJSON a => FilePath -> a -> IO () -- | Efficiently serialize a JSON value as a lazy ByteString. -- -- This is implemented in terms of the ToJSON class's -- toEncoding method. encode :: ToJSON a => a -> ByteString -- | Encode a Foldable as a JSON array. foldable :: (Foldable t, ToJSON a) => t a -> Encoding type GToJSON = GToJSON Value type GToEncoding = GToJSON Encoding -- | Lift the standard toEncoding function through the type -- constructor. toEncoding2 :: (ToJSON2 f, ToJSON a, ToJSON b) => f a b -> Encoding -- | Lift the standard toJSON function through the type constructor. toJSON2 :: (ToJSON2 f, ToJSON a, ToJSON b) => f a b -> Value -- | Lift the standard toEncoding function through the type -- constructor. toEncoding1 :: (ToJSON1 f, ToJSON a) => f a -> Encoding -- | Lift the standard toJSON function through the type constructor. toJSON1 :: (ToJSON1 f, ToJSON a) => f a -> Value -- | A configurable generic JSON encoder. This function applied to -- defaultOptions is used as the default for liftToEncoding -- when the type is an instance of Generic1. genericLiftToEncoding :: (Generic1 f, GToJSON Encoding One Rep1 f) => Options -> a -> Encoding -> [a] -> Encoding -> f a -> Encoding -- | A configurable generic JSON encoder. This function applied to -- defaultOptions is used as the default for toEncoding -- when the type is an instance of Generic. genericToEncoding :: (Generic a, GToJSON Encoding Zero Rep a) => Options -> a -> Encoding -- | A configurable generic JSON creator. This function applied to -- defaultOptions is used as the default for liftToJSON -- when the type is an instance of Generic1. genericLiftToJSON :: (Generic1 f, GToJSON Value One Rep1 f) => Options -> a -> Value -> [a] -> Value -> f a -> Value -- | A configurable generic JSON creator. This function applied to -- defaultOptions is used as the default for toJSON when -- the type is an instance of Generic. genericToJSON :: (Generic a, GToJSON Value Zero Rep a) => Options -> a -> Value -- | A ToArgs value either stores nothing (for ToJSON) or it -- stores the two function arguments that encode occurrences of the type -- parameter (for ToJSON1). data ToArgs res arity a [NoToArgs] :: ToArgs res Zero a [To1Args] :: ToArgs res One a -- | A type that can be converted to JSON. -- -- Instances in general must specify toJSON and -- should (but don't need to) specify toEncoding. -- -- An example type and instance: -- --
--   -- Allow ourselves to write Text literals.
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   data Coord = Coord { x :: Double, y :: Double }
--   
--   instance ToJSON Coord where
--     toJSON (Coord x y) = object ["x" .= x, "y" .= y]
--   
--     toEncoding (Coord x y) = pairs ("x" .= x <> "y" .= y)
--   
-- -- Instead of manually writing your ToJSON instance, there are two -- options to do it automatically: -- -- -- -- To use the second, simply add a deriving Generic -- clause to your datatype and declare a ToJSON instance. If you -- require nothing other than defaultOptions, it is sufficient to -- write (and this is the only alternative where the default -- toJSON implementation is sufficient): -- --
--   {-# LANGUAGE DeriveGeneric #-}
--   
--   import GHC.Generics
--   
--   data Coord = Coord { x :: Double, y :: Double } deriving Generic
--   
--   instance ToJSON Coord where
--       toEncoding = genericToEncoding defaultOptions
--   
-- -- If on the other hand you wish to customize the generic decoding, you -- have to implement both methods: -- --
--   customOptions = defaultOptions
--                   { fieldLabelModifier = map toUpper
--                   }
--   
--   instance ToJSON Coord where
--       toJSON     = genericToJSON customOptions
--       toEncoding = genericToEncoding customOptions
--   
-- -- Previous versions of this library only had the toJSON method. -- Adding toEncoding had to reasons: -- --
    --
  1. toEncoding is more efficient for the common case that the output -- of toJSON is directly serialized to a ByteString. -- Further, expressing either method in terms of the other would be -- non-optimal.
  2. --
  3. The choice of defaults allows a smooth transition for existing -- users: Existing instances that do not define toEncoding still -- compile and have the correct semantics. This is ensured by making the -- default implementation of toEncoding use toJSON. This -- produces correct results, but since it performs an intermediate -- conversion to a Value, it will be less efficient than directly -- emitting an Encoding. (this also means that specifying nothing -- more than instance ToJSON Coord would be sufficient as a -- generically decoding instance, but there probably exists no good -- reason to not specify toEncoding in new instances.)
  4. --
class ToJSON a -- | Convert a Haskell value to a JSON-friendly intermediate type. toJSON :: ToJSON a => a -> Value -- | Encode a Haskell value as JSON. -- -- The default implementation of this method creates an intermediate -- Value using toJSON. This provides source-level -- compatibility for people upgrading from older versions of this -- library, but obviously offers no performance advantage. -- -- To benefit from direct encoding, you must provide an -- implementation for this method. The easiest way to do so is by having -- your types implement Generic using the DeriveGeneric -- extension, and then have GHC generate a method body as follows. -- --
--   instance ToJSON Coord where
--       toEncoding = genericToEncoding defaultOptions
--   
toEncoding :: ToJSON a => a -> Encoding toJSONList :: ToJSON a => [a] -> Value toEncodingList :: ToJSON a => [a] -> Encoding -- | A key-value pair for encoding a JSON object. class KeyValue kv (.=) :: (KeyValue kv, ToJSON v) => Text -> v -> kv -- | Typeclass for types that can be used as the key of a map-like -- container (like Map or HashMap). For example, since -- Text has a ToJSONKey instance and Char has a -- ToJSON instance, we can encode a value of type Map -- Text Char: -- --
--   >>> LBC8.putStrLn $ encode $ Map.fromList [("foo" :: Text, 'a')]
--   {"foo":"a"}
--   
-- -- Since Int also has a ToJSONKey instance, we can -- similarly write: -- --
--   >>> LBC8.putStrLn $ encode $ Map.fromList [(5 :: Int, 'a')]
--   {"5":"a"}
--   
-- -- JSON documents only accept strings as object keys. For any type from -- base that has a natural textual representation, it can be -- expected that its ToJSONKey instance will choose that -- representation. -- -- For data types that lack a natural textual representation, an -- alternative is provided. The map-like container is represented as a -- JSON array instead of a JSON object. Each value in the array is an -- array with exactly two values. The first is the key and the second is -- the value. -- -- For example, values of type '[Text]' cannot be encoded to a string, so -- a Map with keys of type '[Text]' is encoded as follows: -- --
--   >>> LBC8.putStrLn $ encode $ Map.fromList [(["foo","bar","baz" :: Text], 'a')]
--   [[["foo","bar","baz"],"a"]]
--   
-- -- The default implementation of ToJSONKey chooses this method of -- encoding a key, using the ToJSON instance of the type. -- -- To use your own data type as the key in a map, all that is needed is -- to write a ToJSONKey (and possibly a FromJSONKey) -- instance for it. If the type cannot be trivially converted to and from -- Text, it is recommended that ToJSONKeyValue is used. -- Since the default implementations of the typeclass methods can build -- this from a ToJSON instance, there is nothing that needs to be -- written: -- --
--   data Foo = Foo { fooAge :: Int, fooName :: Text }
--     deriving (Eq,Ord,Generic)
--   instance ToJSON Foo
--   instance ToJSONKey Foo
--   
-- -- That's it. We can now write: -- --
--   >>> let m = Map.fromList [(Foo 4 "bar",'a'),(Foo 6 "arg",'b')]
--   
--   >>> LBC8.putStrLn $ encode m
--   [[{"fooName":"bar","fooAge":4},"a"],[{"fooName":"arg","fooAge":6},"b"]]
--   
-- -- The next case to consider is if we have a type that is a newtype -- wrapper around Text. The recommended approach is to use -- generalized newtype deriving: -- --
--   newtype RecordId = RecordId { getRecordId :: Text}
--     deriving (Eq,Ord,ToJSONKey)
--   
-- -- Then we may write: -- --
--   >>> LBC8.putStrLn $ encode $ Map.fromList [(RecordId "abc",'a')]
--   {"abc":"a"}
--   
-- -- Simple sum types are a final case worth considering. Suppose we have: -- --
--   data Color = Red | Green | Blue
--     deriving (Show,Read,Eq,Ord)
--   
-- -- It is possible to get the ToJSONKey instance for free as we did -- with Foo. However, in this case, we have a natural way to go -- to and from Text that does not require any escape sequences. -- So, in this example, ToJSONKeyText will be used instead of -- ToJSONKeyValue. The Show instance can be used to help -- write ToJSONKey: -- --
--   instance ToJSONKey Color where
--     toJSONKey = ToJSONKeyText f g
--       where f = Text.pack . show
--             g = text . Text.pack . show
--             -- text function is from Data.Aeson.Encoding
--   
-- -- The situation of needing to turning function a -> Text -- into a ToJSONKeyFunction is common enough that a special -- combinator is provided for it. The above instance can be rewritten as: -- --
--   instance ToJSONKey Color where
--     toJSONKey = toJSONKeyText (Text.pack . show)
--   
-- -- The performance of the above instance can be improved by not using -- String as an intermediate step when converting to Text. -- One option for improving performance would be to use template haskell -- machinery from the text-show package. However, even with the -- approach, the Encoding (a wrapper around a bytestring builder) -- is generated by encoding the Text to a ByteString, an -- intermediate step that could be avoided. The fastest possible -- implementation would be: -- --
--   -- Assuming that OverloadedStrings is enabled
--   instance ToJSONKey Color where
--     toJSONKey = ToJSONKeyText f g
--       where f x = case x of {Red -> "Red";Green ->"Green";Blue -> "Blue"}
--             g x = case x of {Red -> text "Red";Green -> text "Green";Blue -> text "Blue"}
--             -- text function is from Data.Aeson.Encoding
--   
-- -- This works because GHC can lift the encoded values out of the case -- statements, which means that they are only evaluated once. This -- approach should only be used when there is a serious need to maximize -- performance. class ToJSONKey a -- | Strategy for rendering the key for a map-like container. toJSONKey :: ToJSONKey a => ToJSONKeyFunction a -- | This is similar in spirit to the showsList method of -- Show. It makes it possible to give String keys special -- treatment without using OverlappingInstances. End users -- should always be able to use the default implementation of this -- method. toJSONKeyList :: ToJSONKey a => ToJSONKeyFunction [a] data ToJSONKeyFunction a -- | key is encoded to string, produces object ToJSONKeyText :: !a -> Text -> !a -> Encoding' Text -> ToJSONKeyFunction a -- | key is encoded to value, produces array ToJSONKeyValue :: !a -> Value -> !a -> Encoding -> ToJSONKeyFunction a -- | Lifting of the ToJSON class to unary type constructors. -- -- Instead of manually writing your ToJSON1 instance, there are -- two options to do it automatically: -- -- -- -- To use the second, simply add a deriving Generic1 -- clause to your datatype and declare a ToJSON1 instance for your -- datatype without giving definitions for liftToJSON or -- liftToEncoding. -- -- For example: -- --
--   {-# LANGUAGE DeriveGeneric #-}
--   
--   import GHC.Generics
--   
--   data Pair = Pair { pairFst :: a, pairSnd :: b } deriving Generic1
--   
--   instance ToJSON a => ToJSON1 (Pair a)
--   
-- -- If the default implementation doesn't give exactly the results you -- want, you can customize the generic encoding with only a tiny amount -- of effort, using genericLiftToJSON and -- genericLiftToEncoding with your preferred Options: -- --
--   customOptions = defaultOptions
--                   { fieldLabelModifier = map toUpper
--                   }
--   
--   instance ToJSON a => ToJSON1 (Pair a) where
--       liftToJSON     = genericLiftToJSON customOptions
--       liftToEncoding = genericLiftToEncoding customOptions
--   
-- -- See also ToJSON. class ToJSON1 (f :: * -> *) liftToJSON :: ToJSON1 f => a -> Value -> [a] -> Value -> f a -> Value liftToJSONList :: ToJSON1 f => a -> Value -> [a] -> Value -> [f a] -> Value liftToEncoding :: ToJSON1 f => a -> Encoding -> [a] -> Encoding -> f a -> Encoding liftToEncodingList :: ToJSON1 f => a -> Encoding -> [a] -> Encoding -> [f a] -> Encoding -- | Lifting of the ToJSON class to binary type constructors. -- -- Instead of manually writing your ToJSON2 instance, -- Data.Aeson.TH provides Template Haskell functions which will -- derive an instance at compile time. -- -- The compiler cannot provide a default generic implementation for -- liftToJSON2, unlike toJSON and liftToJSON. class ToJSON2 (f :: * -> * -> *) liftToJSON2 :: ToJSON2 f => a -> Value -> [a] -> Value -> b -> Value -> [b] -> Value -> f a b -> Value liftToJSONList2 :: ToJSON2 f => a -> Value -> [a] -> Value -> b -> Value -> [b] -> Value -> [f a b] -> Value liftToEncoding2 :: ToJSON2 f => a -> Encoding -> [a] -> Encoding -> b -> Encoding -> [b] -> Encoding -> f a b -> Encoding liftToEncodingList2 :: ToJSON2 f => a -> Encoding -> [a] -> Encoding -> b -> Encoding -> [b] -> Encoding -> [f a b] -> Encoding -- | Encode a series of key/value pairs, separated by commas. pairs :: Series -> Encoding -- | Acquire the underlying bytestring builder. fromEncoding :: Encoding' tag -> Builder -- | Often used synonym for Encoding'. type Encoding = Encoding' Value -- | A series of values that, when encoded, should be separated by commas. -- Since 0.11.0.0, the .= operator is overloaded to create -- either (Text, Value) or Series. You can use Series -- when encoding directly to a bytestring builder as in the following -- example: -- --
--   toEncoding (Person name age) = pairs ("name" .= name <> "age" .= age)
--   
data Series -- | Helper for use in combination with .:? to provide default -- values for optional JSON object fields. -- -- This combinator is most useful if the key and value can be absent from -- an object without affecting its validity and we know a default value -- to assign in that case. If the key and value are mandatory, use -- .: instead. -- -- Example usage: -- --
--   v1 <- o .:? "opt_field_with_dfl" .!= "default_val"
--   v2 <- o .:  "mandatory_field"
--   v3 <- o .:? "opt_field2"
--   
(.!=) :: () => Parser Maybe a -> a -> Parser a -- | Retrieve the value associated with the given key of an Object. -- The result is Nothing if the key is not present or -- empty if the value cannot be converted to the desired type. -- -- This differs from .:? by attempting to parse Null the -- same as any other JSON value, instead of interpreting it as -- Nothing. (.:!) :: FromJSON a => Object -> Text -> Parser Maybe a -- | Retrieve the value associated with the given key of an Object. -- The result is Nothing if the key is not present or if its value -- is Null, or empty if the value cannot be converted to -- the desired type. -- -- This accessor is most useful if the key and value can be absent from -- an object without affecting its validity. If the key and value are -- mandatory, use .: instead. (.:?) :: FromJSON a => Object -> Text -> Parser Maybe a -- | Retrieve the value associated with the given key of an Object. -- The result is empty if the key is not present or the value -- cannot be converted to the desired type. -- -- This accessor is appropriate if the key and value must be -- present in an object for it to be valid. If the key and value are -- optional, use .:? instead. (.:) :: FromJSON a => Object -> Text -> Parser a -- | Convert a value from JSON, failing if the types do not match. fromJSON :: FromJSON a => Value -> Result a -- | Decode a nested JSON-encoded string. withEmbeddedJSON :: () => String -> Value -> Parser a -> Value -> Parser a -- | withBool expected f value applies f to the -- Bool when value is a Bool and fails using -- typeMismatch expected otherwise. withBool :: () => String -> Bool -> Parser a -> Value -> Parser a -- | withScientific expected f value applies f to -- the Scientific number when value is a Number -- and fails using typeMismatch expected otherwise. . -- Warning: If you are converting from a scientific to an -- unbounded type such as Integer you may want to add a -- restriction on the size of the exponent (see -- withBoundedScientific) to prevent malicious input from filling -- up the memory of the target system. withScientific :: () => String -> Scientific -> Parser a -> Value -> Parser a -- | withArray expected f value applies f to the -- Array when value is an Array and fails using -- typeMismatch expected otherwise. withArray :: () => String -> Array -> Parser a -> Value -> Parser a -- | withText expected f value applies f to the -- Text when value is a String and fails using -- typeMismatch expected otherwise. withText :: () => String -> Text -> Parser a -> Value -> Parser a -- | withObject expected f value applies f to the -- Object when value is an Object and fails using -- typeMismatch expected otherwise. withObject :: () => String -> Object -> Parser a -> Value -> Parser a -- | Lift the standard parseJSON function through the type -- constructor. parseJSON2 :: (FromJSON2 f, FromJSON a, FromJSON b) => Value -> Parser f a b -- | Lift the standard parseJSON function through the type -- constructor. parseJSON1 :: (FromJSON1 f, FromJSON a) => Value -> Parser f a -- | A configurable generic JSON decoder. This function applied to -- defaultOptions is used as the default for liftParseJSON -- when the type is an instance of Generic1. genericLiftParseJSON :: (Generic1 f, GFromJSON One Rep1 f) => Options -> Value -> Parser a -> Value -> Parser [a] -> Value -> Parser f a -- | A configurable generic JSON decoder. This function applied to -- defaultOptions is used as the default for parseJSON when -- the type is an instance of Generic. genericParseJSON :: (Generic a, GFromJSON Zero Rep a) => Options -> Value -> Parser a -- | Class of generic representation types that can be converted from JSON. class GFromJSON arity (f :: * -> *) -- | This method (applied to defaultOptions) is used as the default -- generic implementation of parseJSON (if the arity is -- Zero) or liftParseJSON (if the arity is -- One). gParseJSON :: GFromJSON arity f => Options -> FromArgs arity a -> Value -> Parser f a -- | A FromArgs value either stores nothing (for FromJSON) or -- it stores the two function arguments that decode occurrences of the -- type parameter (for FromJSON1). data FromArgs arity a [NoFromArgs] :: FromArgs Zero a [From1Args] :: FromArgs One a -- | A type that can be converted from JSON, with the possibility of -- failure. -- -- In many cases, you can get the compiler to generate parsing code for -- you (see below). To begin, let's cover writing an instance by hand. -- -- There are various reasons a conversion could fail. For example, an -- Object could be missing a required key, an Array could -- be of the wrong size, or a value could be of an incompatible type. -- -- The basic ways to signal a failed conversion are as follows: -- -- -- -- An example type and instance using typeMismatch: -- --
--   -- Allow ourselves to write Text literals.
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   data Coord = Coord { x :: Double, y :: Double }
--   
--   instance FromJSON Coord where
--       parseJSON (Object v) = Coord
--           <$> v .: "x"
--           <*> v .: "y"
--   
--       -- We do not expect a non-Object value here.
--       -- We could use mzero to fail, but typeMismatch
--       -- gives a much more informative error message.
--       parseJSON invalid    = typeMismatch "Coord" invalid
--   
-- -- For this common case of only being concerned with a single type of -- JSON value, the functions withObject, withNumber, etc. -- are provided. Their use is to be preferred when possible, since they -- are more terse. Using withObject, we can rewrite the above -- instance (assuming the same language extension and data type) as: -- --
--   instance FromJSON Coord where
--       parseJSON = withObject "Coord" $ \v -> Coord
--           <$> v .: "x"
--           <*> v .: "y"
--   
-- -- Instead of manually writing your FromJSON instance, there are -- two options to do it automatically: -- -- -- -- To use the second, simply add a deriving Generic -- clause to your datatype and declare a FromJSON instance for -- your datatype without giving a definition for parseJSON. -- -- For example, the previous example can be simplified to just: -- --
--   {-# LANGUAGE DeriveGeneric #-}
--   
--   import GHC.Generics
--   
--   data Coord = Coord { x :: Double, y :: Double } deriving Generic
--   
--   instance FromJSON Coord
--   
-- -- The default implementation will be equivalent to parseJSON = -- genericParseJSON defaultOptions; If you need -- different options, you can customize the generic decoding by defining: -- --
--   customOptions = defaultOptions
--                   { fieldLabelModifier = map toUpper
--                   }
--   
--   instance FromJSON Coord where
--       parseJSON = genericParseJSON customOptions
--   
class FromJSON a parseJSON :: FromJSON a => Value -> Parser a parseJSONList :: FromJSON a => Value -> Parser [a] -- | Read the docs for ToJSONKey first. This class is a conversion -- in the opposite direction. If you have a newtype wrapper around -- Text, the recommended way to define instances is with -- generalized newtype deriving: -- --
--   newtype SomeId = SomeId { getSomeId :: Text }
--     deriving (Eq,Ord,Hashable,FromJSONKey)
--   
class FromJSONKey a -- | Strategy for parsing the key of a map-like container. fromJSONKey :: FromJSONKey a => FromJSONKeyFunction a -- | This is similar in spirit to the readList method of -- Read. It makes it possible to give String keys special -- treatment without using OverlappingInstances. End users -- should always be able to use the default implementation of this -- method. fromJSONKeyList :: FromJSONKey a => FromJSONKeyFunction [a] -- | This type is related to ToJSONKeyFunction. If -- FromJSONKeyValue is used in the FromJSONKey instance, -- then ToJSONKeyValue should be used in the ToJSONKey -- instance. The other three data constructors for this type all -- correspond to ToJSONKeyText. Strictly speaking, -- FromJSONKeyTextParser is more powerful than -- FromJSONKeyText, which is in turn more powerful than -- FromJSONKeyCoerce. For performance reasons, these exist as -- three options instead of one. data FromJSONKeyFunction a -- | uses coerce (unsafeCoerce in older GHCs) FromJSONKeyCoerce :: !CoerceText a -> FromJSONKeyFunction a -- | conversion from Text that always succeeds FromJSONKeyText :: !Text -> a -> FromJSONKeyFunction a -- | conversion from Text that may fail FromJSONKeyTextParser :: !Text -> Parser a -> FromJSONKeyFunction a -- | conversion for non-textual keys FromJSONKeyValue :: !Value -> Parser a -> FromJSONKeyFunction a -- | Lifting of the FromJSON class to unary type constructors. -- -- Instead of manually writing your FromJSON1 instance, there are -- two options to do it automatically: -- -- -- -- To use the second, simply add a deriving Generic1 -- clause to your datatype and declare a FromJSON1 instance for -- your datatype without giving a definition for liftParseJSON. -- -- For example: -- --
--   {-# LANGUAGE DeriveGeneric #-}
--   
--   import GHC.Generics
--   
--   data Pair a b = Pair { pairFst :: a, pairSnd :: b } deriving Generic1
--   
--   instance FromJSON a => FromJSON1 (Pair a)
--   
-- -- If the default implementation doesn't give exactly the results you -- want, you can customize the generic decoding with only a tiny amount -- of effort, using genericLiftParseJSON with your preferred -- Options: -- --
--   customOptions = defaultOptions
--                   { fieldLabelModifier = map toUpper
--                   }
--   
--   instance FromJSON a => FromJSON1 (Pair a) where
--       liftParseJSON = genericLiftParseJSON customOptions
--   
class FromJSON1 (f :: * -> *) liftParseJSON :: FromJSON1 f => Value -> Parser a -> Value -> Parser [a] -> Value -> Parser f a liftParseJSONList :: FromJSON1 f => Value -> Parser a -> Value -> Parser [a] -> Value -> Parser [f a] -- | Lifting of the FromJSON class to binary type constructors. -- -- Instead of manually writing your FromJSON2 instance, -- Data.Aeson.TH provides Template Haskell functions which will -- derive an instance at compile time. class FromJSON2 (f :: * -> * -> *) liftParseJSON2 :: FromJSON2 f => Value -> Parser a -> Value -> Parser [a] -> Value -> Parser b -> Value -> Parser [b] -> Value -> Parser f a b liftParseJSONList2 :: FromJSON2 f => Value -> Parser a -> Value -> Parser [a] -> Value -> Parser b -> Value -> Parser [b] -> Value -> Parser [f a b] -- | Parse a top-level JSON value. -- -- This is a strict version of json which avoids building up -- thunks during parsing; it performs all conversions immediately. Prefer -- this version if most of the JSON data needs to be accessed. -- -- This function is an alias for value'. In aeson 0.8 and earlier, -- it parsed only object or array types, in conformance with the -- now-obsolete RFC 4627. json' :: Parser Value -- | Parse a top-level JSON value. -- -- The conversion of a parsed value to a Haskell value is deferred until -- the Haskell value is needed. This may improve performance if only a -- subset of the results of conversions are needed, but at a cost in -- thunk allocation. -- -- This function is an alias for value. In aeson 0.8 and earlier, -- it parsed only object or array types, in conformance with the -- now-obsolete RFC 4627. json :: Parser Value -- | Better version of camelTo. Example where it works better: -- --
--   camelTo '_' 'CamelAPICase' == "camel_apicase"
--   camelTo2 '_' 'CamelAPICase' == "camel_api_case"
--   
camelTo2 :: Char -> String -> String -- | Default TaggedObject SumEncoding options: -- --
--   defaultTaggedObject = TaggedObject
--                         { tagFieldName      = "tag"
--                         , contentsFieldName = "contents"
--                         }
--   
defaultTaggedObject :: SumEncoding -- | Default encoding Options: -- --
--   Options
--   { fieldLabelModifier      = id
--   , constructorTagModifier  = id
--   , allNullaryToStringTag   = True
--   , omitNothingFields       = False
--   , sumEncoding             = defaultTaggedObject
--   , unwrapUnaryRecords      = False
--   , tagSingleConstructors   = False
--   }
--   
defaultOptions :: Options -- | Create a Value from a list of name/value Pairs. If -- duplicate keys arise, earlier keys and their associated values win. object :: [Pair] -> Value -- | The result of running a Parser. data Result a Error :: String -> Result a Success :: a -> Result a -- | A JSON "object" (key/value map). type Object = HashMap Text Value -- | A JSON "array" (sequence). type Array = Vector Value -- | A JSON value represented as a Haskell value. data Value Object :: !Object -> Value Array :: !Array -> Value String :: !Text -> Value Number :: !Scientific -> Value Bool :: !Bool -> Value Null :: Value -- | A newtype wrapper for UTCTime that uses the same non-standard -- serialization format as Microsoft .NET, whose System.DateTime -- type is by default serialized to JSON as in the following example: -- --
--   /Date(1302547608878)/
--   
-- -- The number represents milliseconds since the Unix epoch. newtype DotNetTime DotNetTime :: UTCTime -> DotNetTime -- | Acquire the underlying value. [fromDotNetTime] :: DotNetTime -> UTCTime -- | Options that specify how to encode/decode your datatype to/from JSON. -- -- Options can be set using record syntax on defaultOptions with -- the fields below. data Options -- | Specifies how to encode constructors of a sum datatype. data SumEncoding -- | A constructor will be encoded to an object with a field -- tagFieldName which specifies the constructor tag (modified by -- the constructorTagModifier). If the constructor is a record the -- encoded record fields will be unpacked into this object. So make sure -- that your record doesn't have a field with the same label as the -- tagFieldName. Otherwise the tag gets overwritten by the encoded -- value of that field! If the constructor is not a record the encoded -- constructor contents will be stored under the contentsFieldName -- field. TaggedObject :: String -> String -> SumEncoding [tagFieldName] :: SumEncoding -> String [contentsFieldName] :: SumEncoding -> String -- | Constructor names won't be encoded. Instead only the contents of the -- constructor will be encoded as if the type had a single constructor. -- JSON encodings have to be disjoint for decoding to work properly. -- -- When decoding, constructors are tried in the order of definition. If -- some encodings overlap, the first one defined will succeed. -- -- Note: Nullary constructors are encoded as strings (using -- constructorTagModifier). Having a nullary constructor alongside -- a single field constructor that encodes to a string leads to -- ambiguity. -- -- Note: Only the last error is kept when decoding, so in the case -- of malformed JSON, only an error for the last constructor will be -- reported. UntaggedValue :: SumEncoding -- | A constructor will be encoded to an object with a single field named -- after the constructor tag (modified by the -- constructorTagModifier) which maps to the encoded contents of -- the constructor. ObjectWithSingleField :: SumEncoding -- | A constructor will be encoded to a 2-element array where the first -- element is the tag of the constructor (modified by the -- constructorTagModifier) and the second element the encoded -- contents of the constructor. TwoElemArray :: SumEncoding -- | A type-level indicator that ToJSON or FromJSON is -- being derived generically. data Zero -- | A type-level indicator that ToJSON1 or FromJSON1 is -- being derived generically. data One aesonQQ :: QuasiQuoter -- | A ThreadId is an abstract type representing a handle to a -- thread. ThreadId is an instance of Eq, Ord and -- Show, where the Ord instance implements an arbitrary -- total ordering over ThreadIds. The Show instance lets -- you convert an arbitrary-valued ThreadId to string form; -- showing a ThreadId value is occasionally useful when debugging -- or diagnosing the behaviour of a concurrent program. -- -- Note: in GHC, if you have a ThreadId, you essentially -- have a pointer to the thread itself. This means the thread itself -- can't be garbage collected until you drop the ThreadId. This -- misfeature will hopefully be corrected at a later date. data ThreadId -- | True if bound threads are supported. If -- rtsSupportsBoundThreads is False, -- isCurrentThreadBound will always return False and both -- forkOS and runInBoundThread will fail. rtsSupportsBoundThreads :: Bool -- | Chan is an abstract type representing an unbounded FIFO -- channel. data Chan a -- | Superclass for asynchronous exceptions. data SomeAsyncException [SomeAsyncException] :: SomeAsyncException -- | Exceptions that occur in the IO monad. An -- IOException records a more specific error type, a descriptive -- string and maybe the handle that was used when the error was flagged. data IOException -- | Any type that you wish to throw or catch as an exception must be an -- instance of the Exception class. The simplest case is a new -- exception type directly below the root: -- --
--   data MyException = ThisException | ThatException
--       deriving Show
--   
--   instance Exception MyException
--   
-- -- The default method definitions in the Exception class do what -- we need in this case. You can now throw and catch -- ThisException and ThatException as exceptions: -- --
--   *Main> throw ThisException `catch` \e -> putStrLn ("Caught " ++ show (e :: MyException))
--   Caught ThisException
--   
-- -- In more complicated examples, you may wish to define a whole hierarchy -- of exceptions: -- --
--   ---------------------------------------------------------------------
--   -- Make the root exception type for all the exceptions in a compiler
--   
--   data SomeCompilerException = forall e . Exception e => SomeCompilerException e
--   
--   instance Show SomeCompilerException where
--       show (SomeCompilerException e) = show e
--   
--   instance Exception SomeCompilerException
--   
--   compilerExceptionToException :: Exception e => e -> SomeException
--   compilerExceptionToException = toException . SomeCompilerException
--   
--   compilerExceptionFromException :: Exception e => SomeException -> Maybe e
--   compilerExceptionFromException x = do
--       SomeCompilerException a <- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make a subhierarchy for exceptions in the frontend of the compiler
--   
--   data SomeFrontendException = forall e . Exception e => SomeFrontendException e
--   
--   instance Show SomeFrontendException where
--       show (SomeFrontendException e) = show e
--   
--   instance Exception SomeFrontendException where
--       toException = compilerExceptionToException
--       fromException = compilerExceptionFromException
--   
--   frontendExceptionToException :: Exception e => e -> SomeException
--   frontendExceptionToException = toException . SomeFrontendException
--   
--   frontendExceptionFromException :: Exception e => SomeException -> Maybe e
--   frontendExceptionFromException x = do
--       SomeFrontendException a <- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make an exception type for a particular frontend compiler exception
--   
--   data MismatchedParentheses = MismatchedParentheses
--       deriving Show
--   
--   instance Exception MismatchedParentheses where
--       toException   = frontendExceptionToException
--       fromException = frontendExceptionFromException
--   
-- -- We can now catch a MismatchedParentheses exception as -- MismatchedParentheses, SomeFrontendException or -- SomeCompilerException, but not other types, e.g. -- IOException: -- --
--   *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
--   Caught MismatchedParentheses
--   *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeFrontendException))
--   Caught MismatchedParentheses
--   *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeCompilerException))
--   Caught MismatchedParentheses
--   *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: IOException))
--   *** Exception: MismatchedParentheses
--   
class (Typeable e, Show e) => Exception e toException :: Exception e => e -> SomeException fromException :: Exception e => SomeException -> Maybe e -- | Render this exception value in a human-friendly manner. -- -- Default implementation: show. displayException :: Exception e => e -> String -- | asProxyTypeOf is a type-restricted version of const. It -- is usually used as an infix operator, and its typing forces its first -- argument (which is usually overloaded) to have the same type as the -- tag of the second. -- --
--   >>> import Data.Word
--   
--   >>> :type asProxyTypeOf 123 (Proxy :: Proxy Word8)
--   asProxyTypeOf 123 (Proxy :: Proxy Word8) :: Word8
--   
-- -- Note the lower-case proxy in the definition. This allows any -- type constructor with just one argument to be passed to the function, -- for example we could also write -- --
--   >>> import Data.Word
--   
--   >>> :type asProxyTypeOf 123 (Just (undefined :: Word8))
--   asProxyTypeOf 123 (Just (undefined :: Word8)) :: Word8
--   
asProxyTypeOf :: () => a -> proxy a -> a -- | Proxy is a type that holds no data, but has a phantom parameter -- of arbitrary type (or even kind). Its use is to provide type -- information, even though there is no value available of that type (or -- it may be too costly to create one). -- -- Historically, Proxy :: Proxy a is a safer -- alternative to the 'undefined :: a' idiom. -- --
--   >>> Proxy :: Proxy (Void, Int -> Int)
--   Proxy
--   
-- -- Proxy can even hold types of higher kinds, -- --
--   >>> Proxy :: Proxy Either
--   Proxy
--   
-- --
--   >>> Proxy :: Proxy Functor
--   Proxy
--   
-- --
--   >>> Proxy :: Proxy complicatedStructure
--   Proxy
--   
data Proxy (t :: k) :: forall k. () => k -> * Proxy :: Proxy -- | A concrete, promotable proxy type, for use at the kind level There are -- no instances for this because it is intended at the kind level only data KProxy t KProxy :: KProxy t -- | Type-level If. If True a b ==> a; If -- False a b ==> b -- | An MVar (pronounced "em-var") is a synchronising variable, used -- for communication between concurrent threads. It can be thought of as -- a a box, which may be empty or full. data MVar a -- | The SomeException type is the root of the exception type -- hierarchy. When an exception of type e is thrown, behind the -- scenes it is encapsulated in a SomeException. data SomeException [SomeException] :: SomeException -- | The parameterizable maybe monad, obtained by composing an arbitrary -- monad with the Maybe monad. -- -- Computations are actions that may produce a value or exit. -- -- The return function yields a computation that produces that -- value, while >>= sequences two subcomputations, exiting -- if either computation does. newtype MaybeT (m :: * -> *) a MaybeT :: m Maybe a -> MaybeT a [runMaybeT] :: MaybeT a -> m Maybe a -- | A monad transformer that adds exceptions to other monads. -- -- ExceptT constructs a monad parameterized over two things: -- -- -- -- The return function yields a computation that produces the -- given value, while >>= sequences two subcomputations, -- exiting on the first exception. newtype ExceptT e (m :: * -> *) a ExceptT :: m Either e a -> ExceptT e a -- | Monads which allow their actions to be run in IO. -- -- While MonadIO allows an IO action to be lifted into -- another monad, this class captures the opposite concept: allowing you -- to capture the monadic context. Note that, in order to meet the laws -- given below, the intuition is that a monad must have no monadic state, -- but may have monadic context. This essentially limits -- MonadUnliftIO to ReaderT and IdentityT -- transformers on top of IO. -- -- Laws. For any value u returned by askUnliftIO, it must -- meet the monad transformer laws as reformulated for -- MonadUnliftIO: -- -- -- -- The third is a currently nameless law which ensures that the current -- context is preserved. -- -- -- -- If you have a name for this, please submit it in a pull request for -- great glory. class MonadIO m => MonadUnliftIO (m :: * -> *) -- | A type class for extensible product. -- -- We provide instances for tuples up to 12 elements by default. You can -- define your own instance of Has, but most of the time tuples -- will do fine. class Has a t getter :: Has a t => t -> a modifier :: Has a t => a -> a -> t -> t hasLens :: Has a t => Lens t a -- | Register a number of metrics related to garbage collector behavior. -- -- To enable GC statistics collection, either run your program with -- --
--   +RTS -T
--   
-- -- or compile it with -- --
--   -with-rtsopts=-T
--   
-- -- The runtime overhead of -T is very small so it's safe to -- always leave it enabled. -- -- Registered counters: -- -- -- -- Registered gauges: -- -- registerGcMetrics :: Store -> IO () -- | A mutable metric store. data Store -- | The metric store associated with the server. If you want to add metric -- to the default store created by forkServer you need to use this -- function to retrieve it. serverMetricStore :: Server -> Store -- | Display all environment variables, for convenience showEnv :: IO () -- | Unset Environment using a value of class ToEnv unsetEnvironment' :: ToEnv a => a -> IO Either String () -- | Unset Environment from a ToEnv constrained type unsetEnvironment :: () => EnvList a -> IO Either String () -- | Set environment directly using a value of class ToEnv setEnvironment' :: ToEnv a => a -> IO Either String () -- | Set environment via a ToEnv constrained type setEnvironment :: () => EnvList a -> IO Either String () -- | Environment retrieval with failure info decodeEnv :: FromEnv a => IO Either String a -- | Smart constructor, environment creation helper. makeEnv :: () => [EnvVar] -> EnvList a -- | Meant for specifying a custom Option for environment retrieval -- --
--   instance FromEnv PGConfig where
--     fromEnv = gFromEnvCustom Option { dropPrefixCount = 8, customPrefix = "PG" }
--   
gFromEnvCustom :: (DefConfig a, Generic a, GFromEnv Rep a) => Option -> Parser a -- | Environment variable getter returning Maybe envMaybe :: Var a => String -> Parser Maybe a -- | Environment variable getter. Fails if the variable is not set or fails -- to parse. env :: Var a => String -> Parser a -- | For use with Generics, no FromEnv typeclass necessary -- --
--   getPgConfig :: IO (Either String ConnectInfo)
--   getPgConfig = runEnv $ gFromEnvCustom defOption
--   
runEnv :: () => Parser a -> IO Either String a -- | Parser Monad for environment variable retrieval newtype Parser a Parser :: ExceptT String IO a -> Parser a [runParser] :: Parser a -> ExceptT String IO a -- | FromEnv Typeclass w/ Generic default implementation class FromEnv a fromEnv :: FromEnv a => Parser a -- | Type class for objects which have a default configuration. class DefConfig a defConfig :: DefConfig a => a -- | For customizing environment variable generation data Option Option :: Int -> String -> Option -- | Applied first [dropPrefixCount] :: Option -> Int -- | Converted toUpper [customPrefix] :: Option -> String -- | Type class for objects which can be converted to a set of environment -- variable settings. class ToEnv a -- | Convert an object into a list of environment variable settings. toEnv :: ToEnv a => a -> EnvList a -- | List of environment variables. Captures a "phantom type" which allows -- the type checker to detect the proper implementation of toEnv to use. data EnvList a -- | Class for converting to / from an environment variable class Typeable a => Var a -- | Convert a value into an environment variable. toVar :: Var a => a -> String -- | Parse an environment variable. fromVar :: Var a => String -> Maybe a -- | fmap specialized to ExceptT, given a name symmetric to -- fmapLT fmapRT :: Monad m => a -> b -> ExceptT l m a -> ExceptT l m b -- | Analogous to isRight, but for ExceptT isRightT :: Monad m => ExceptT a m b -> m Bool -- | Analogous to isLeft, but for ExceptT isLeftT :: Monad m => ExceptT a m b -> m Bool -- | fmap specialized to Either, given a name symmetric to -- fmapL fmapR :: () => a -> b -> Either l a -> Either l b -- | Returns whether argument is a Right isRight :: () => Either a b -> Bool -- | Returns whether argument is a Left isLeft :: () => Either a b -> Bool -- | Analogous to isNothing, but for MaybeT isNothingT :: Monad m => MaybeT m a -> m Bool -- | Analogous to isJust, but for MaybeT isJustT :: Monad m => MaybeT m a -> m Bool -- | Analogous to Nothing and equivalent to mzero nothing :: Monad m => MaybeT m a -- | Analogous to Just and equivalent to return just :: Monad m => a -> MaybeT m a -- | Case analysis for MaybeT -- -- Use the first argument if the MaybeT computation fails, -- otherwise apply the function to the successful result. maybeT :: Monad m => m b -> a -> m b -> MaybeT m a -> m b -- | Convert an applicative Maybe value into the ExceptT -- monad -- -- Named version of (!?) with arguments flipped failWithM :: Applicative m => e -> m Maybe a -> ExceptT e m a -- | Convert a Maybe value into the ExceptT monad -- -- Named version of (??) with arguments flipped failWith :: Applicative m => e -> Maybe a -> ExceptT e m a -- | An infix form of fromMaybe with arguments flipped. (?:) :: () => Maybe a -> a -> a infixr 0 ?: -- | Convert an applicative Maybe value into the ExceptT -- monad (!?) :: Applicative m => m Maybe a -> e -> ExceptT e m a -- | Lift a Maybe to the MaybeT monad hoistMaybe :: Monad m => Maybe b -> MaybeT m b -- | Tag the Nothing value of a MaybeT noteT :: Monad m => a -> MaybeT m b -> ExceptT a m b -- | Tag the Nothing value of a Maybe note :: () => a -> Maybe b -> Either a b -- | Suppress the Left value of an ExceptT hushT :: Monad m => ExceptT a m b -> MaybeT m b -- | Suppress the Left value of an Either hush :: () => Either a b -> Maybe b -- | Upgrade an Either to an ExceptT hoistEither :: Monad m => Either e a -> ExceptT e m a -- | Transform the left and right value bimapExceptT :: Functor m => e -> f -> a -> b -> ExceptT e m a -> ExceptT f m b -- | Fold an ExceptT by providing one continuation for each -- constructor exceptT :: Monad m => a -> m c -> b -> m c -> ExceptT a m b -> m c -- | Run multiple Either computations and succeed if all of them -- succeed -- -- mappends all successes or failures newtype AllE e r AllE :: Either e r -> AllE e r [runAllE] :: AllE e r -> Either e r -- | Run multiple Either computations and succeed if any of them -- succeed -- -- mappends all successes or failures newtype AnyE e r AnyE :: Either e r -> AnyE e r [runAnyE] :: AnyE e r -> Either e r -- | Transform the computation inside a MaybeT. -- -- mapMaybeT :: () => m Maybe a -> n Maybe b -> MaybeT m a -> MaybeT n b -- | Lift a catchE operation to the new monad. liftCatch :: () => Catch e m Maybe a -> Catch e MaybeT m a -- | The inverse of ExceptT. runExceptT :: () => ExceptT e m a -> m Either e a -- | A class for monads which allow exceptions to be caught, in particular -- exceptions which were thrown by throwM. -- -- Instances should obey the following law: -- --
--   catch (throwM e) f = f e
--   
-- -- Note that the ability to catch an exception does not guarantee -- that we can deal with all possible exit points from a computation. -- Some monads, such as continuation-based stacks, allow for more than -- just a success/failure strategy, and therefore catch -- cannot be used by those monads to properly implement a function -- such as finally. For more information, see MonadMask. class MonadThrow m => MonadCatch (m :: * -> *) -- | Logger Type. data LogType -- | No logging. LogNone :: LogType -- | Logging to stdout. BufSize is a buffer size for each -- capability. LogStdout :: BufSize -> LogType -- | Logging to stderr. BufSize is a buffer size for each -- capability. LogStderr :: BufSize -> LogType -- | Logging to a file. BufSize is a buffer size for each -- capability. LogFileNoRotate :: FilePath -> BufSize -> LogType -- | Logging to a file. BufSize is a buffer size for each -- capability. File rotation is done on-demand. LogFile :: FileLogSpec -> BufSize -> LogType -- | Logging with a log and flush action. run flush after log each message. LogCallback :: LogStr -> IO () -> IO () -> LogType -- | The default buffer size (4,096 bytes). defaultBufSize :: BufSize -- | Like encodePathSegments, but without the initial slash. encodePathSegmentsRelative :: [Text] -> Builder -- | Convert value to HTTP API data. -- -- WARNING: Do not derive this using DeriveAnyClass as -- the generated instance will loop indefinitely. class ToHttpApiData a -- | Convert to URL path piece. toUrlPiece :: ToHttpApiData a => a -> Text -- | Convert to a URL path piece, making sure to encode any special chars. -- The default definition uses encodePathSegmentsRelative, but -- this may be overriden with a more efficient version. toEncodedUrlPiece :: ToHttpApiData a => a -> Builder -- | Convert to HTTP header value. toHeader :: ToHttpApiData a => a -> ByteString -- | Convert to query param value. toQueryParam :: ToHttpApiData a => a -> Text -- | Parse value from HTTP API data. -- -- WARNING: Do not derive this using DeriveAnyClass as -- the generated instance will loop indefinitely. class FromHttpApiData a -- | Parse URL path piece. parseUrlPiece :: FromHttpApiData a => Text -> Either Text a -- | Parse HTTP header value. parseHeader :: FromHttpApiData a => ByteString -> Either Text a -- | Parse query param value. parseQueryParam :: FromHttpApiData a => Text -> Either Text a -- | Represents a general universal resource identifier using its component -- parts. -- -- For example, for the URI -- --
--   foo://anonymous@www.haskell.org:42/ghc?query#frag
--   
-- -- the components are: data URI URI :: String -> Maybe URIAuth -> String -> String -> String -> URI -- |
--   foo:
--   
[uriScheme] :: URI -> String -- |
--   //anonymous@www.haskell.org:42
--   
[uriAuthority] :: URI -> Maybe URIAuth -- |
--   /ghc
--   
[uriPath] :: URI -> String -- |
--   ?query
--   
[uriQuery] :: URI -> String -- |
--   #frag
--   
[uriFragment] :: URI -> String -- | Use the default response timeout -- -- When used on a Request, means: use the manager's timeout value -- -- When used on a ManagerSettings, means: default to 30 seconds responseTimeoutDefault :: ResponseTimeout -- | Do not have a response timeout responseTimeoutNone :: ResponseTimeout -- | Specify a response timeout in microseconds responseTimeoutMicro :: Int -> ResponseTimeout -- | Set the proxy override value, for both HTTP (insecure) and HTTPS -- (insecure) connections. -- -- Since 0.4.7 managerSetProxy :: ProxyOverride -> ManagerSettings -> ManagerSettings -- | Set the proxy override value, only for HTTPS (secure) connections. -- -- Since 0.4.7 managerSetSecureProxy :: ProxyOverride -> ManagerSettings -> ManagerSettings -- | Set the proxy override value, only for HTTP (insecure) connections. -- -- Since 0.4.7 managerSetInsecureProxy :: ProxyOverride -> ManagerSettings -> ManagerSettings -- | A variant of withResponse which keeps a history of all -- redirects performed in the interim, together with the first 1024 bytes -- of their response bodies. -- -- Since 0.4.1 withResponseHistory :: () => Request -> Manager -> HistoriedResponse BodyReader -> IO a -> IO a -- | A variant of responseOpen which keeps a history of all -- redirects performed in the interim, together with the first 1024 bytes -- of their response bodies. -- -- Since 0.4.1 responseOpenHistory :: Request -> Manager -> IO HistoriedResponse BodyReader -- | A datatype holding information on redirected requests and the final -- response. -- -- Since 0.4.1 data HistoriedResponse body -- | Perform an action using a Connection acquired from the given -- Manager. -- -- You should use this only when you have to read and write interactively -- through the connection (e.g. connection by the WebSocket protocol). withConnection :: () => Request -> Manager -> Connection -> IO a -> IO a -- | Close any open resources associated with the given Response. -- In general, this will either close an active Connection or -- return it to the Manager to be reused. -- -- Since 0.1.0 responseClose :: () => Response a -> IO () -- | The most low-level function for initiating an HTTP request. -- -- The first argument to this function gives a full specification on the -- request: the host to connect to, whether to use SSL, headers, etc. -- Please see Request for full details. The second argument -- specifies which Manager should be used. -- -- This function then returns a Response with a BodyReader. -- The Response contains the status code and headers that were -- sent back to us, and the BodyReader contains the body of the -- request. Note that this BodyReader allows you to have fully -- interleaved IO actions during your HTTP download, making it possible -- to download very large responses in constant memory. -- -- An important note: the response body returned by this function -- represents a live HTTP connection. As such, if you do not use the -- response body, an open socket will be retained indefinitely. You must -- be certain to call responseClose on this response to free up -- resources. -- -- This function automatically performs any necessary redirects, as -- specified by the redirectCount setting. -- -- When implementing a (reverse) proxy using this function or relating -- functions, it's wise to remove Transfer-Encoding:, Content-Length:, -- Content-Encoding: and Accept-Encoding: from request and response -- headers to be relayed. -- -- Since 0.1.0 responseOpen :: Request -> Manager -> IO Response BodyReader -- | A convenient wrapper around withResponse which ignores the -- response body. This is useful, for example, when performing a HEAD -- request. -- -- Since 0.3.2 httpNoBody :: Request -> Manager -> IO Response () -- | A convenience wrapper around withResponse which reads in the -- entire response body and immediately closes the connection. Note that -- this function performs fully strict I/O, and only uses a lazy -- ByteString in its response for memory efficiency. If you are -- anticipating a large response body, you are encouraged to use -- withResponse and brRead instead. -- -- Since 0.1.0 httpLbs :: Request -> Manager -> IO Response ByteString -- | Perform a Request using a connection acquired from the given -- Manager, and then provide the Response to the given -- function. This function is fully exception safe, guaranteeing that the -- response will be closed when the inner function exits. It is defined -- as: -- --
--   withResponse req man f = bracket (responseOpen req man) responseClose f
--   
-- -- It is recommended that you use this function in place of explicit -- calls to responseOpen and responseClose. -- -- You will need to use functions such as brRead to consume the -- response body. -- -- Since 0.1.0 withResponse :: () => Request -> Manager -> Response BodyReader -> IO a -> IO a -- | Turn a SetCookie into a Cookie, if it is valid generateCookie :: SetCookie -> Request -> UTCTime -> Bool -> Maybe Cookie -- | Insert a cookie created by generateCookie into the cookie jar (or not -- if it shouldn't be allowed in) insertCheckedCookie :: Cookie -> CookieJar -> Bool -> CookieJar -- | This corresponds to the algorithm described in Section 5.3 "Storage -- Model" This function consists of calling generateCookie -- followed by insertCheckedCookie. Use this function if you plan -- to do both in a row. generateCookie and -- insertCheckedCookie are only provided for more fine-grained -- control. receiveSetCookie :: SetCookie -> Request -> UTCTime -> Bool -> CookieJar -> CookieJar -- | This applies receiveSetCookie to a given Response updateCookieJar :: () => Response a -> Request -> UTCTime -> CookieJar -> (CookieJar, Response a) -- | This corresponds to the algorithm described in Section 5.4 "The Cookie -- Header" computeCookieString :: Request -> CookieJar -> UTCTime -> Bool -> (ByteString, CookieJar) -- | This applies the computeCookieString to a given Request insertCookiesIntoRequest :: Request -> CookieJar -> UTCTime -> (Request, CookieJar) -- | This corresponds to the eviction algorithm described in Section 5.3 -- "Storage Model" evictExpiredCookies :: CookieJar -> UTCTime -> CookieJar removeExistingCookieFromCookieJar :: Cookie -> CookieJar -> (Maybe Cookie, CookieJar) destroyCookieJar :: CookieJar -> [Cookie] createCookieJar :: [Cookie] -> CookieJar -- | This corresponds to the subcomponent algorithm entitled "Path-Match" -- detailed in section 5.1.4 pathMatches :: ByteString -> ByteString -> Bool -- | This corresponds to the subcomponent algorithm entitled "Paths" -- detailed in section 5.1.4 defaultPath :: Request -> ByteString -- | This corresponds to the subcomponent algorithm entitled "Domain -- Matching" detailed in section 5.1.3 domainMatches :: ByteString -> ByteString -> Bool isIpAddress :: ByteString -> Bool -- | The default proxy settings for a manager. In particular: if the -- http_proxy (or https_proxy) environment variable is -- set, use it. Otherwise, use the values in the Request. -- -- Since 0.4.7 defaultProxy :: ProxyOverride -- | Same as proxyEnvironment, but instead of default environment -- variable names, allows you to set your own name. -- -- Since 0.4.7 proxyEnvironmentNamed :: Text -> Maybe Proxy -> ProxyOverride -- | Get the proxy settings from the default environment variable -- (http_proxy for insecure, https_proxy for secure). -- If no variable is set, then fall back to the given value. -- Nothing is equivalent to noProxy, Just is -- equivalent to useProxy. -- -- Since 0.4.7 proxyEnvironment :: Maybe Proxy -> ProxyOverride -- | Use the given proxy settings, regardless of the proxy value in the -- Request. -- -- Since 0.4.7 useProxy :: Proxy -> ProxyOverride -- | Never connect using a proxy, regardless of the proxy value in the -- Request. -- -- Since 0.4.7 noProxy :: ProxyOverride -- | Get the proxy settings from the Request itself. -- -- Since 0.4.7 proxyFromRequest :: ProxyOverride -- | Create, use and close a Manager. -- -- Since 0.2.1 withManager :: () => ManagerSettings -> Manager -> IO a -> IO a -- | Close all connections in a Manager. -- -- Note that this doesn't affect currently in-flight connections, meaning -- you can safely use it without hurting any queries you may have -- concurrently running. -- -- Since 0.1.0 closeManager :: Manager -> IO () -- | Create a Manager. The Manager will be shut down -- automatically via garbage collection. -- -- Creating a new Manager is a relatively expensive operation, you -- are advised to share a single Manager between requests instead. -- -- The first argument to this function is often -- defaultManagerSettings, though add-on libraries may provide a -- recommended replacement. -- -- Since 0.1.0 newManager :: ManagerSettings -> IO Manager -- | Default value for ManagerSettings. -- -- Note that this value does not have support for SSL/TLS. If you -- need to make any https connections, please use the http-client-tls -- package, which provides a tlsManagerSettings value. -- -- Since 0.1.0 defaultManagerSettings :: ManagerSettings -- | Same as rawConnectionModifySocket, but also takes in a chunk -- size. rawConnectionModifySocketSize :: Socket -> IO () -> IO Int -> Maybe HostAddress -> String -> Int -> IO Connection -- | A value for the managerRawConnection setting, but also allows -- you to modify the underlying Socket to set additional -- settings. For a motivating use case, see: -- https://github.com/snoyberg/http-client/issues/71. -- -- Since 0.3.8 rawConnectionModifySocket :: Socket -> IO () -> IO Maybe HostAddress -> String -> Int -> IO Connection -- | Send a file as the request body, while observing streaming progress -- via a PopObserver. Observations are made between reading and -- sending a chunk. -- -- It is expected that the file size does not change between calling -- observedStreamFile and making any requests using this request -- body. -- -- Since 0.4.9 observedStreamFile :: StreamFileStatus -> IO () -> FilePath -> IO RequestBody -- | Send a file as the request body. -- -- It is expected that the file size does not change between calling -- streamFile and making any requests using this request body. -- -- Since 0.4.9 streamFile :: FilePath -> IO RequestBody -- | Set the query string to the given key/value pairs. setQueryStringPartialEscape :: [(ByteString, [EscapeItem])] -> Request -> Request -- | Set the query string to the given key/value pairs. -- -- Since 0.3.6 setQueryString :: [(ByteString, Maybe ByteString)] -> Request -> Request -- | Modify the request so that non-2XX status codes generate a runtime -- StatusCodeException, by using throwErrorStatusCodes setRequestCheckStatus :: Request -> Request -- | Modify the request so that non-2XX status codes do not generate a -- runtime StatusCodeException. setRequestIgnoreStatus :: Request -> Request -- | Add url-encoded parameters to the Request. -- -- This sets a new requestBody, adds a content-type request header -- and changes the method to POST. -- -- Since 0.1.0 urlEncodedBody :: [(ByteString, ByteString)] -> Request -> Request -- | Add a Proxy-Authorization header (with the specified username and -- password) to the given Request. Ignore error handling: -- --
--   applyBasicProxyAuth "user" "pass" <$> parseRequest "http://example.org"
--   
-- -- Since 0.3.4 applyBasicProxyAuth :: ByteString -> ByteString -> Request -> Request -- | Add a Basic Auth header (with the specified user name and password) to -- the given Request. Ignore error handling: -- --
--   applyBasicAuth "user" "pass" $ parseRequest_ url
--   
-- -- NOTE: The function applyDigestAuth is provided by the -- http-client-tls package instead of this package due to extra -- dependencies. Please use that package if you need to use digest -- authentication. -- -- Since 0.1.0 applyBasicAuth :: ByteString -> ByteString -> Request -> Request -- | A default request value, a GET request of localhost/:80, with an empty -- request body. -- -- Note that the default checkResponse does nothing. defaultRequest :: Request -- | Extract a URI from the request. -- -- Since 0.1.0 getUri :: Request -> URI -- | Same as requestFromURI, but if the conversion would fail, -- throws an impure exception. requestFromURI_ :: URI -> Request -- | Convert a URI into a Request. -- -- This can fail if the given URI is not absolute, or if the -- URI scheme is not "http" or "https". In these -- cases the function will throw an error via MonadThrow. -- -- This function defaults some of the values in Request, such as -- setting method to GET and requestHeaders -- to []. -- -- A Request created by this function won't cause exceptions on -- non-2XX response status codes. requestFromURI :: MonadThrow m => URI -> m Request -- | Same as parseRequest, but parse errors cause an impure -- exception. Mostly useful for static strings which are known to be -- correctly formatted. parseRequest_ :: String -> Request -- | Convert a URL into a Request. -- -- This function defaults some of the values in Request, such as -- setting method to GET and requestHeaders -- to []. -- -- Since this function uses MonadThrow, the return monad can be -- anything that is an instance of MonadThrow, such as IO -- or Maybe. -- -- You can place the request method at the beginning of the URL separated -- by a space, e.g.: -- -- @@ parseRequest "POST http://httpbin.org/post" @@ -- -- Note that the request method must be provided as all capital letters. -- -- A Request created by this function won't cause exceptions on -- non-2XX response status codes. -- -- To create a request which throws on non-2XX status codes, see -- parseUrlThrow parseRequest :: MonadThrow m => String -> m Request -- | Throws a StatusCodeException wrapped in -- HttpExceptionRequest, if the response's status code indicates -- an error (if it isn't 2xx). This can be used to implement -- checkResponse. throwErrorStatusCodes :: MonadIO m => Request -> Response BodyReader -> m () -- | Same as parseRequest, except will throw an HttpException -- in the event of a non-2XX response. This uses -- throwErrorStatusCodes to implement checkResponse. parseUrlThrow :: MonadThrow m => String -> m Request -- | Deprecated synonym for parseUrlThrow. You probably want -- parseRequest or parseRequest_ instead. parseUrl :: MonadThrow m => String -> m Request -- | Strictly consume all remaining chunks of data from the stream. -- -- Since 0.1.0 brConsume :: BodyReader -> IO [ByteString] -- | Continuously call brRead, building up a lazy ByteString until a -- chunk is constructed that is at least as many bytes as requested. -- -- Since 0.4.20 brReadSome :: BodyReader -> Int -> IO ByteString -- | Get a single chunk of data from the response body, or an empty -- bytestring if no more data is available. -- -- Note that in order to consume the entire request body, you will need -- to repeatedly call this function until you receive an empty -- ByteString as a result. -- -- Since 0.1.0 brRead :: BodyReader -> IO ByteString -- | Create a new Connection from a Socket. socketConnection :: Socket -> Int -> IO Connection -- | Create a new Connection from a read, write, and close function. makeConnection :: IO ByteString -> ByteString -> IO () -> IO () -> IO Connection -- | An IO action that represents an incoming response body coming -- from the server. Data provided by this action has already been -- gunzipped and de-chunked, and respects any content-length headers -- present. -- -- The action gets a single chunk of data from the response body, or an -- empty bytestring if no more data is available. -- -- Since 0.4.0 type BodyReader = IO ByteString -- | An exception which may be generated by this library data HttpException -- | Most exceptions are specific to a Request. Inspect the -- HttpExceptionContent value for details on what occurred. HttpExceptionRequest :: Request -> HttpExceptionContent -> HttpException -- | A URL (first field) is invalid for a given reason (second argument). InvalidUrlException :: String -> String -> HttpException data HttpExceptionContent -- | Generated by the parseUrlThrow function when the server -- returns a non-2XX response status code. -- -- May include the beginning of the response body. StatusCodeException :: Response () -> ByteString -> HttpExceptionContent -- | The server responded with too many redirects for a request. -- -- Contains the list of encountered responses containing redirects in -- reverse chronological order; including last redirect, which triggered -- the exception and was not followed. TooManyRedirects :: [Response ByteString] -> HttpExceptionContent -- | Either too many headers, or too many total bytes in a single header, -- were returned by the server, and the memory exhaustion protection in -- this library has kicked in. OverlongHeaders :: HttpExceptionContent -- | The server took too long to return a response. This can be altered via -- responseTimeout or managerResponseTimeout. ResponseTimeout :: HttpExceptionContent -- | Attempting to connect to the server timed out. ConnectionTimeout :: HttpExceptionContent -- | An exception occurred when trying to connect to the server. ConnectionFailure :: SomeException -> HttpExceptionContent -- | The status line returned by the server could not be parsed. InvalidStatusLine :: ByteString -> HttpExceptionContent -- | The given response header line could not be parsed InvalidHeader :: ByteString -> HttpExceptionContent -- | An exception was raised by an underlying library when performing the -- request. Most often, this is caused by a failing socket action or a -- TLS exception. InternalException :: SomeException -> HttpExceptionContent -- | A non-200 status code was returned when trying to connect to the proxy -- server on the given host and port. ProxyConnectException :: ByteString -> Int -> Status -> HttpExceptionContent -- | No response data was received from the server at all. This exception -- may deserve special handling within the library, since it may indicate -- that a pipelining has been used, and a connection thought to be open -- was in fact closed. NoResponseDataReceived :: HttpExceptionContent -- | Exception thrown when using a Manager which does not have -- support for secure connections. Typically, you will want to use -- tlsManagerSettings from http-client-tls to overcome -- this. TlsNotSupported :: HttpExceptionContent -- | The request body provided did not match the expected size. -- -- Provides the expected and actual size. WrongRequestBodyStreamSize :: Word64 -> Word64 -> HttpExceptionContent -- | The returned response body is too short. Provides the expected size -- and actual size. ResponseBodyTooShort :: Word64 -> Word64 -> HttpExceptionContent -- | A chunked response body had invalid headers. InvalidChunkHeaders :: HttpExceptionContent -- | An incomplete set of response headers were returned. IncompleteHeaders :: HttpExceptionContent -- | The host we tried to connect to is invalid (e.g., an empty string). InvalidDestinationHost :: ByteString -> HttpExceptionContent -- | An exception was thrown when inflating a response body. HttpZlibException :: ZlibException -> HttpExceptionContent -- | Values in the proxy environment variable were invalid. Provides the -- environment variable name and its value. InvalidProxyEnvironmentVariable :: Text -> Text -> HttpExceptionContent -- | Attempted to use a Connection which was already closed ConnectionClosed :: HttpExceptionContent -- | Proxy settings are not valid (Windows specific currently) @since 0.5.7 InvalidProxySettings :: Text -> HttpExceptionContent data Cookie Cookie :: ByteString -> ByteString -> UTCTime -> ByteString -> ByteString -> UTCTime -> UTCTime -> Bool -> Bool -> Bool -> Bool -> Cookie [cookie_name] :: Cookie -> ByteString [cookie_value] :: Cookie -> ByteString [cookie_expiry_time] :: Cookie -> UTCTime [cookie_domain] :: Cookie -> ByteString [cookie_path] :: Cookie -> ByteString [cookie_creation_time] :: Cookie -> UTCTime [cookie_last_access_time] :: Cookie -> UTCTime [cookie_persistent] :: Cookie -> Bool [cookie_host_only] :: Cookie -> Bool [cookie_secure_only] :: Cookie -> Bool [cookie_http_only] :: Cookie -> Bool data CookieJar -- | The host name of the HTTP proxy. proxyHost :: Proxy -> ByteString -- | The port number of the HTTP proxy. proxyPort :: Proxy -> Int -- | When using one of the RequestBodyStream / -- RequestBodyStreamChunked constructors, you must ensure that the -- GivesPopper can be called multiple times. Usually this is not a -- problem. -- -- The RequestBodyStreamChunked will send a chunked request body. -- Note that not all servers support this. Only use -- RequestBodyStreamChunked if you know the server you're sending -- to supports chunked request bodies. -- -- Since 0.1.0 data RequestBody RequestBodyLBS :: ByteString -> RequestBody RequestBodyBS :: ByteString -> RequestBody RequestBodyBuilder :: Int64 -> Builder -> RequestBody RequestBodyStream :: Int64 -> GivesPopper () -> RequestBody RequestBodyStreamChunked :: GivesPopper () -> RequestBody -- | Allows creation of a RequestBody inside the IO -- monad, which is useful for making easier APIs (like -- setRequestBodyFile). RequestBodyIO :: IO RequestBody -> RequestBody -- | A function which generates successive chunks of a request body, -- provider a single empty bytestring when no more data is available. -- -- Since 0.1.0 type Popper = IO ByteString -- | A function which must be provided with a Popper. -- -- Since 0.1.0 type NeedsPopper a = Popper -> IO a -- | A function which will provide a Popper to a NeedsPopper. -- This seemingly convoluted structure allows for creation of request -- bodies which allocate scarce resources in an exception safe manner. -- -- Since 0.1.0 type GivesPopper a = NeedsPopper a -> IO a -- | All information on how to connect to a host and what should be sent in -- the HTTP request. -- -- If you simply wish to download from a URL, see parseRequest. -- -- The constructor for this data type is not exposed. Instead, you should -- use either the defaultRequest value, or parseRequest -- to construct from a URL, and then use the records below to make -- modifications. This approach allows http-client to add configuration -- options without breaking backwards compatibility. -- -- For example, to construct a POST request, you could do something like: -- --
--   initReq <- parseRequest "http://www.example.com/path"
--   let req = initReq
--               { method = "POST"
--               }
--   
-- -- For more information, please see -- http://www.yesodweb.com/book/settings-types. -- -- Since 0.1.0 data Request -- | How to deal with timing out a response data ResponseTimeout -- | A simple representation of the HTTP response. -- -- Since 0.1.0 data Response body -- | Settings for a Manager. Please use the -- defaultManagerSettings function and then modify individual -- settings. For more information, see -- http://www.yesodweb.com/book/settings-types. -- -- Since 0.1.0 data ManagerSettings -- | How the HTTP proxy server settings should be discovered. -- -- Since 0.4.7 data ProxyOverride -- | Keeps track of open connections for keep-alive. -- -- If possible, you should share a single Manager between multiple -- threads and requests. -- -- Since 0.1.0 data Manager class HasHttpManager a getHttpManager :: HasHttpManager a => a -> Manager -- | Status of streaming a request body from a file. -- -- Since 0.4.9 data StreamFileStatus StreamFileStatus :: Int64 -> Int64 -> Int -> StreamFileStatus [fileSize] :: StreamFileStatus -> Int64 [readSoFar] :: StreamFileStatus -> Int64 [thisChunkSize] :: StreamFileStatus -> Int -- | Query. -- -- General form: a=b&c=d, but if the value is Nothing, it becomes -- a&c=d. type Query = [QueryItem] writeLinkHeader :: [Link] -> Text writeLink :: Link -> Text -- | Parses a Link header, returns a Maybe. parseLinkHeaderBS :: ByteString -> Maybe [Link] -- | Parses a Link header, returns an Either, where Left is the Attoparsec -- error string (probably not a useful one). parseLinkHeaderBS' :: ByteString -> Either String [Link] -- | Parses a Link header, returns a Maybe. parseLinkHeader :: Text -> Maybe [Link] -- | Parses a Link header, returns an Either, where Left is the Attoparsec -- error string (probably not a useful one). parseLinkHeader' :: Text -> Either String [Link] -- | The Attoparsec parser for the Link header. linkHeader :: Parser [Link] lnk :: String -> [(LinkParam, Text)] -> Maybe Link -- | Extracts the parameters from the link. linkParams :: Link -> [(LinkParam, Text)] -- | Extracts the URI from the link. href :: Link -> URI -- | The link attribute key. data LinkParam Rel :: LinkParam Anchor :: LinkParam Rev :: LinkParam Hreflang :: LinkParam Media :: LinkParam Title :: LinkParam Title' :: LinkParam ContentType :: LinkParam Other :: Text -> LinkParam -- | HTTP 2.0 http20 :: HttpVersion -- | HTTP 1.1 http11 :: HttpVersion -- | HTTP 1.0 http10 :: HttpVersion -- | HTTP 0.9 http09 :: HttpVersion -- | HTTP Version. -- -- Note that the Show instance is intended merely for debugging. data HttpVersion HttpVersion :: !Int -> !Int -> HttpVersion [httpMajor] :: HttpVersion -> !Int [httpMinor] :: HttpVersion -> !Int -- | Types which can, and commonly are, converted to Query are in -- this class. -- -- You can use lists of simple key value pairs, with ByteString -- (strict, or lazy: ByteString), Text, or String as -- the key/value types. You can also have the value type lifted into a -- Maybe to support keys without values; and finally it is possible to -- put each pair into a Maybe for key-value pairs that aren't always -- present. class QueryLike a -- | Convert to Query. toQuery :: QueryLike a => a -> Query -- | Convert PartialEscapeQuery to a Builder. renderQueryBuilderPartialEscape :: Bool -> PartialEscapeQuery -> Builder -- | Convert PartialEscapeQuery to ByteString. renderQueryPartialEscape :: Bool -> PartialEscapeQuery -> ByteString -- | Decode a whole path (path segments + query). decodePath :: ByteString -> ([Text], Query) -- | Encode a whole path (path segments + query). encodePath :: [Text] -> Query -> Builder -- | Extract whole path (path segments + query) from a RFC 2616 -- Request-URI. -- --
--   >>> extractPath "/path"
--   "/path"
--   
-- --
--   >>> extractPath "http://example.com:8080/path"
--   "/path"
--   
-- --
--   >>> extractPath "http://example.com"
--   "/"
--   
-- --
--   >>> extractPath ""
--   "/"
--   
extractPath :: ByteString -> ByteString -- | Parse a list of path segments from a valid URL fragment. decodePathSegments :: ByteString -> [Text] -- | Encodes a list of path segments into a valid URL fragment. -- -- This function takes the following three steps: -- -- -- -- For example: -- --
--   encodePathSegments [\"foo\", \"bar\", \"baz\"]
--   
-- -- "/foo/bar/baz" -- --
--   encodePathSegments [\"foo bar\", \"baz\/bin\"]
--   
-- -- "/foo%20bar/baz%2Fbin" -- --
--   encodePathSegments [\"שלום\"]
--   
-- -- "/%D7%A9%D7%9C%D7%95%D7%9D" -- -- Huge thanks to Jeremy Shaw who created the original implementation of -- this function in web-routes and did such thorough research to -- determine all correct escaping procedures. encodePathSegments :: [Text] -> Builder -- | Percent-decoding. urlDecode :: Bool -> ByteString -> ByteString -- | Percent-encoding for URLs. urlEncode :: Bool -> ByteString -> ByteString -- | Percent-encoding for URLs (using Builder). urlEncodeBuilder :: Bool -> ByteString -> Builder -- | Parse SimpleQuery from a ByteString. parseSimpleQuery :: ByteString -> SimpleQuery -- | Split out the query string into a list of keys and values. A few -- importants points: -- -- parseQuery :: ByteString -> Query -- | Convert SimpleQuery to ByteString. renderSimpleQuery :: Bool -> SimpleQuery -> ByteString -- | Convert Query to ByteString. renderQuery :: Bool -> Query -> ByteString -- | Convert Query to a Builder. renderQueryBuilder :: Bool -> Query -> Builder -- | Convert SimpleQuery to Query. simpleQueryToQuery :: SimpleQuery -> Query -- | Parse QueryText from a ByteString. See parseQuery -- for details. parseQueryText :: ByteString -> QueryText -- | Convert Query to QueryText (leniently decoding the -- UTF-8). queryToQueryText :: Query -> QueryText -- | Convert QueryText to a Builder. renderQueryText :: Bool -> QueryText -> Builder -- | Convert QueryText to Query. queryTextToQuery :: QueryText -> Query -- | Query item type QueryItem = (ByteString, Maybe ByteString) -- | Like Query, but with Text instead of ByteString -- (UTF8-encoded). type QueryText = [(Text, Maybe Text)] -- | Simplified Query item type without support for parameter-less items. type SimpleQueryItem = (ByteString, ByteString) -- | Simplified Query type without support for parameter-less items. type SimpleQuery = [SimpleQueryItem] -- | For some URIs characters must not be URI encoded, eg + or -- : in -- q=a+language:haskell+created:2009-01-01..2009-02-01&sort=stars The -- character list unreservedPI instead of unreservedQS would solve this. -- But we explicitly decide what part to encode. This is mandatory when -- searching for +: q=%2B+language:haskell. data EscapeItem QE :: ByteString -> EscapeItem QN :: ByteString -> EscapeItem -- | Query item type PartialEscapeQueryItem = (ByteString, [EscapeItem]) -- | Query with some chars that should not be escaped. -- -- General form: a=b&c=d:e+f&g=h type PartialEscapeQuery = [PartialEscapeQueryItem] -- | Server Error class statusIsServerError :: Status -> Bool -- | Client Error class statusIsClientError :: Status -> Bool -- | Redirection class statusIsRedirection :: Status -> Bool -- | Successful class statusIsSuccessful :: Status -> Bool -- | Informational class statusIsInformational :: Status -> Bool -- | Network Authentication Required 511 (RFC 6585) networkAuthenticationRequired511 :: Status -- | Network Authentication Required 511 (RFC 6585) status511 :: Status -- | HTTP Version Not Supported 505 httpVersionNotSupported505 :: Status -- | HTTP Version Not Supported 505 status505 :: Status -- | Gateway Timeout 504 gatewayTimeout504 :: Status -- | Gateway Timeout 504 status504 :: Status -- | Service Unavailable 503 serviceUnavailable503 :: Status -- | Service Unavailable 503 status503 :: Status -- | Bad Gateway 502 badGateway502 :: Status -- | Bad Gateway 502 status502 :: Status -- | Not Implemented 501 notImplemented501 :: Status -- | Not Implemented 501 status501 :: Status -- | Internal Server Error 500 internalServerError500 :: Status -- | Internal Server Error 500 status500 :: Status -- | Request Header Fields Too Large 431 (RFC 6585) requestHeaderFieldsTooLarge431 :: Status -- | Request Header Fields Too Large 431 (RFC 6585) status431 :: Status -- | Too Many Requests 429 (RFC 6585) tooManyRequests429 :: Status -- | Too Many Requests 429 (RFC 6585) status429 :: Status -- | Precondition Required 428 (RFC 6585) preconditionRequired428 :: Status -- | Precondition Required 428 (RFC 6585) status428 :: Status -- | Unprocessable Entity 422 (RFC 4918) unprocessableEntity422 :: Status -- | Unprocessable Entity 422 (RFC 4918) status422 :: Status -- | I'm a teapot 418 imATeapot418 :: Status -- | I'm a teapot 418 status418 :: Status -- | Expectation Failed 417 expectationFailed417 :: Status -- | Expectation Failed 417 status417 :: Status -- | Requested Range Not Satisfiable 416 requestedRangeNotSatisfiable416 :: Status -- | Requested Range Not Satisfiable 416 status416 :: Status -- | Unsupported Media Type 415 unsupportedMediaType415 :: Status -- | Unsupported Media Type 415 status415 :: Status -- | Request-URI Too Long 414 requestURITooLong414 :: Status -- | Request-URI Too Long 414 status414 :: Status -- | Request Entity Too Large 413 requestEntityTooLarge413 :: Status -- | Request Entity Too Large 413 status413 :: Status -- | Precondition Failed 412 preconditionFailed412 :: Status -- | Precondition Failed 412 status412 :: Status -- | Length Required 411 lengthRequired411 :: Status -- | Length Required 411 status411 :: Status -- | Gone 410 gone410 :: Status -- | Gone 410 status410 :: Status -- | Conflict 409 conflict409 :: Status -- | Conflict 409 status409 :: Status -- | Request Timeout 408 requestTimeout408 :: Status -- | Request Timeout 408 status408 :: Status -- | Proxy Authentication Required 407 proxyAuthenticationRequired407 :: Status -- | Proxy Authentication Required 407 status407 :: Status -- | Not Acceptable 406 notAcceptable406 :: Status -- | Not Acceptable 406 status406 :: Status -- | Method Not Allowed 405 methodNotAllowed405 :: Status -- | Method Not Allowed 405 status405 :: Status -- | Not Found 404 notFound404 :: Status -- | Not Found 404 status404 :: Status -- | Forbidden 403 forbidden403 :: Status -- | Forbidden 403 status403 :: Status -- | Payment Required 402 paymentRequired402 :: Status -- | Payment Required 402 status402 :: Status -- | Unauthorized 401 unauthorized401 :: Status -- | Unauthorized 401 status401 :: Status -- | Bad Request 400 badRequest400 :: Status -- | Bad Request 400 status400 :: Status -- | Permanent Redirect 308 permanentRedirect308 :: Status -- | Permanent Redirect 308 status308 :: Status -- | Temporary Redirect 307 temporaryRedirect307 :: Status -- | Temporary Redirect 307 status307 :: Status -- | Use Proxy 305 useProxy305 :: Status -- | Use Proxy 305 status305 :: Status -- | Not Modified 304 notModified304 :: Status -- | Not Modified 304 status304 :: Status -- | See Other 303 seeOther303 :: Status -- | See Other 303 status303 :: Status -- | Found 302 found302 :: Status -- | Found 302 status302 :: Status -- | Moved Permanently 301 movedPermanently301 :: Status -- | Moved Permanently 301 status301 :: Status -- | Multiple Choices 300 multipleChoices300 :: Status -- | Multiple Choices 300 status300 :: Status -- | Partial Content 206 partialContent206 :: Status -- | Partial Content 206 status206 :: Status -- | Reset Content 205 resetContent205 :: Status -- | Reset Content 205 status205 :: Status -- | No Content 204 noContent204 :: Status -- | No Content 204 status204 :: Status -- | Non-Authoritative Information 203 nonAuthoritative203 :: Status -- | Non-Authoritative Information 203 status203 :: Status -- | Accepted 202 accepted202 :: Status -- | Accepted 202 status202 :: Status -- | Created 201 created201 :: Status -- | Created 201 status201 :: Status -- | OK 200 ok200 :: Status -- | OK 200 status200 :: Status -- | Switching Protocols 101 switchingProtocols101 :: Status -- | Switching Protocols 101 status101 :: Status -- | Continue 100 continue100 :: Status -- | Continue 100 status100 :: Status -- | Create a Status from status code and message. mkStatus :: Int -> ByteString -> Status -- | HTTP Status. -- -- Only the statusCode is used for comparisons. -- -- Please use mkStatus to create status codes from code and -- message, or the Enum instance or the status code constants -- (like ok200). There might be additional record members in the -- future. -- -- Note that the Show instance is only for debugging. data Status Status :: Int -> ByteString -> Status [statusCode] :: Status -> Int [statusMessage] :: Status -> ByteString -- | Convert a StdMethod to a ByteString. renderStdMethod :: StdMethod -> Method -- | Convert an algebraic method to a ByteString. renderMethod :: Either ByteString StdMethod -> Method -- | Convert a method ByteString to a StdMethod if -- possible. parseMethod :: Method -> Either ByteString StdMethod -- | HTTP Method constants. methodPatch :: Method -- | HTTP Method constants. methodOptions :: Method -- | HTTP Method constants. methodConnect :: Method -- | HTTP Method constants. methodTrace :: Method -- | HTTP Method constants. methodDelete :: Method -- | HTTP Method constants. methodPut :: Method -- | HTTP Method constants. methodHead :: Method -- | HTTP Method constants. methodPost :: Method -- | HTTP Method constants. methodGet :: Method -- | HTTP method (flat string type). type Method = ByteString -- | HTTP standard method (as defined by RFC 2616, and PATCH which is -- defined by RFC 5789). data StdMethod GET :: StdMethod POST :: StdMethod HEAD :: StdMethod PUT :: StdMethod DELETE :: StdMethod TRACE :: StdMethod CONNECT :: StdMethod OPTIONS :: StdMethod PATCH :: StdMethod -- | Parse the value of a Range header into a ByteRanges. -- --
--   >>> parseByteRanges "error"
--   Nothing
--   
--   >>> parseByteRanges "bytes=0-499"
--   Just [ByteRangeFromTo 0 499]
--   
--   >>> parseByteRanges "bytes=500-999"
--   Just [ByteRangeFromTo 500 999]
--   
--   >>> parseByteRanges "bytes=-500"
--   Just [ByteRangeSuffix 500]
--   
--   >>> parseByteRanges "bytes=9500-"
--   Just [ByteRangeFrom 9500]
--   
--   >>> parseByteRanges "bytes=0-0,-1"
--   Just [ByteRangeFromTo 0 0,ByteRangeSuffix 1]
--   
--   >>> parseByteRanges "bytes=500-600,601-999"
--   Just [ByteRangeFromTo 500 600,ByteRangeFromTo 601 999]
--   
--   >>> parseByteRanges "bytes=500-700,601-999"
--   Just [ByteRangeFromTo 500 700,ByteRangeFromTo 601 999]
--   
parseByteRanges :: ByteString -> Maybe ByteRanges renderByteRanges :: ByteRanges -> ByteString renderByteRangesBuilder :: ByteRanges -> Builder renderByteRange :: ByteRange -> ByteString renderByteRangeBuilder :: ByteRange -> Builder -- | HTTP Header names according to -- https://tools.ietf.org/html/rfc6265#section-4 hCookie :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hUserAgent :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hServer :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hReferer :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hRange :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hLocation :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hLastModified :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hIfRange :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hIfModifiedSince :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hDate :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hContentType :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hContentMD5 :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hContentLength :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hContentEncoding :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hConnection :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hCacheControl :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hAuthorization :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hAcceptLanguage :: HeaderName -- | HTTP Header names according to -- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html hAccept :: HeaderName -- | Header name type HeaderName = CI ByteString -- | Request Headers type RequestHeaders = [Header] -- | Response Headers type ResponseHeaders = [Header] -- | RFC 2616 Byte range (individual). -- -- Negative indices are not allowed! data ByteRange ByteRangeFrom :: !Integer -> ByteRange ByteRangeFromTo :: !Integer -> !Integer -> ByteRange ByteRangeSuffix :: !Integer -> ByteRange -- | RFC 2616 Byte ranges (set). type ByteRanges = [ByteRange] -- | Set the Label to the Shown value of whatever you pass -- in. -- -- label' :: (MonadIO m, MonadMetrics m, Show a) => Text -> a -> m () -- | Set the Label to the given Text value. -- -- label :: (MonadIO m, MonadMetrics m) => Text -> Text -> m () -- | Record the time of executing the given action in seconds. Defers to -- timed'. -- -- timed :: (MonadIO m, MonadMetrics m, MonadMask m) => Text -> m a -> m a -- | Record the time taken to perform the action, under several names at -- once. The number is stored in a Distribution and is converted -- to the specified Resolution. -- -- This is useful to store the same durations data sectioned by different -- criteria, e.g.: -- --
--   timedList Seconds ["request.byUser." <> userName, "request.byType." <> requestType] $ do
--       ...
--   
-- -- So you will have "request.byUser.someuser" storing duration -- distribution for requests of user "someuser" of any type; and -- "request.byType.sometype" storing duration distribution for -- requests of type "sometype" from any user. timedList :: (MonadIO m, MonadMetrics m, MonadMask m) => Resolution -> [Text] -> m a -> m a -- | Record the time taken to perform the named action. The number is -- stored in a Distribution and is converted to the specified -- Resolution. -- -- timed' :: (MonadIO m, MonadMetrics m, MonadMask m) => Resolution -> Text -> m a -> m a -- | A type specialized version of gauge' to avoid ambiguous types. -- -- gauge :: (MonadIO m, MonadMetrics m) => Text -> Int -> m () -- | Set the value of the named Gauge. -- -- gauge' :: (MonadIO m, MonadMetrics m, Integral int) => Text -> int -> m () -- | Add the value to the named Distribution. -- -- distribution :: (MonadIO m, MonadMetrics m) => Text -> Double -> m () -- | A type specialized version of counter' to avoid ambiguous type -- errors. -- -- counter :: (MonadIO m, MonadMetrics m) => Text -> Int -> m () -- | Adds the value to the named Counter. -- -- counter' :: (MonadIO m, MonadMetrics m, Integral int) => Text -> int -> m () -- | Increment the named counter by 1. -- -- increment :: (MonadIO m, MonadMetrics m) => Text -> m () -- | A type can be an instance of MonadMetrics if it can provide a -- Metrics somehow. Commonly, this will be implemented as a -- ReaderT where some field in the environment is the -- Metrics data. -- -- class Monad m => MonadMetrics (m :: * -> *) getMetrics :: MonadMetrics m => m Metrics -- | A lens into the Store provided by the Metrics. -- -- metricsStore :: Lens' Metrics Store -- | A lens into the Labels provided by the Metrics. -- -- metricsLabels :: Lens' Metrics IORef HashMap Text Label -- | A lens into the Gauges provided by the Metrics. -- -- metricsGauges :: Lens' Metrics IORef HashMap Text Gauge -- | A lens into the Counters provided by the Metrics. -- -- metricsCounters :: Lens' Metrics IORef HashMap Text Counter -- | A container for metrics used by the MonadMetrics class. -- -- data Metrics -- | A type representing the resolution of time to use for the -- timed metric. -- -- data Resolution Nanoseconds :: Resolution Microseconds :: Resolution Milliseconds :: Resolution Seconds :: Resolution Minutes :: Resolution Hours :: Resolution Days :: Resolution -- | Is used within a monadic computation to begin exception processing. throwError :: MonadError e m => e -> m a fragment :: URI -> String query :: URI -> String path :: URI -> String authority :: URI -> String scheme :: URI -> String unreserved :: Char -> Bool reserved :: Char -> Bool escapeString :: String -> Char -> Bool -> String parseabsoluteURI :: String -> Maybe URI -- | Path segment normalization; cf. RFC3986 section 6.2.2.3 normalizePathSegments :: String -> String -- | Encoding normalization; cf. RFC3986 section 6.2.2.2 normalizeEscape :: String -> String -- | Case normalization; cf. RFC3986 section 6.2.2.1 NOTE: authority case -- normalization is not performed normalizeCase :: String -> String -- | Returns a new URI which represents the relative location of the -- first URI with respect to the second URI. Thus, the -- values supplied are expected to be absolute URIs, and the result -- returned may be a relative URI. -- -- Example: -- --
--   "http://example.com/Root/sub1/name2#frag"
--     `relativeFrom` "http://example.com/Root/sub2/name2#frag"
--     == "../sub1/name2#frag"
--   
-- -- There is no single correct implementation of this function, but any -- acceptable implementation must satisfy the following: -- --
--   (uabs `relativeFrom` ubase) `relativeTo` ubase == uabs
--   
-- -- For any valid absolute URI. (cf. -- http://lists.w3.org/Archives/Public/uri/2003Jan/0008.html -- http://lists.w3.org/Archives/Public/uri/2003Jan/0005.html) relativeFrom :: URI -> URI -> URI -- | Returns the segments of the path component. E.g., pathSegments -- $ parseURI "http://example.org/foo/bar/baz" == ["foo", -- "bar", "baz"] pathSegments :: URI -> [String] -- | Returns a new URI which represents the value of the first -- URI interpreted as relative to the second URI. -- -- Algorithm from RFC3986 [3], section 5.2 relativeTo :: URI -> URI -> URI -- | Returns a new URI which represents the value of the first -- URI interpreted as relative to the second URI. For -- example: -- --
--   "foo" `relativeTo` "http://bar.org/" = "http://bar.org/foo"
--   "http:foo" `nonStrictRelativeTo` "http://bar.org/" = "http://bar.org/foo"
--   
-- -- Algorithm from RFC3986 [3], section 5.2.2 nonStrictRelativeTo :: URI -> URI -> URI -- | Turns all instances of escaped characters in the string back into -- literal characters. unEscapeString :: String -> String -- | Can be used to make a string valid for use in a URI. escapeURIString :: Char -> Bool -> String -> String -- | Escape character if supplied predicate is not satisfied, otherwise -- return character as singleton string. escapeURIChar :: Char -> Bool -> Char -> String -- | Returns True if the character is allowed unescaped in a URI -- component. -- --
--   >>> escapeURIString isUnescapedInURIComponent "http://haskell.org:80?some_param=true&other_param=їґ"
--   "http%3A%2F%2Fhaskell.org%3A80%3Fsome_param%3Dtrue%26other_param%3D%D1%97%D2%91"
--   
isUnescapedInURIComponent :: Char -> Bool -- | Returns True if the character is allowed unescaped in a URI. -- --
--   >>> escapeURIString isUnescapedInURI "http://haskell.org:80?some_param=true&other_param=їґ"
--   "http://haskell.org:80?some_param=true&other_param=%D1%97%D2%91"
--   
isUnescapedInURI :: Char -> Bool -- | Returns True if the character is allowed in a URI. isAllowedInURI :: Char -> Bool -- | Turn a URI into a string. -- -- Uses a supplied function to map the userinfo part of the URI. -- -- The Show instance for URI uses a mapping that hides any password that -- may be present in the URI. Use this function with argument id -- to preserve the password in the formatted output. uriToString :: String -> String -> URI -> ShowS -- | Returns True if the character is an "unreserved" character in a -- URI. These characters do not need to be escaped in a URI. The only -- characters allowed in a URI are either "reserved", "unreserved", or an -- escape sequence (% followed by two hex digits). isUnreserved :: Char -> Bool -- | Returns True if the character is a "reserved" character in a -- URI. To include a literal instance of one of these characters in a -- component of a URI, it must be escaped. isReserved :: Char -> Bool uriIsRelative :: URI -> Bool uriIsAbsolute :: URI -> Bool -- | Test if string contains a valid IPv4 address isIPv4address :: String -> Bool -- | Test if string contains a valid IPv6 address isIPv6address :: String -> Bool -- | Test if string contains a valid absolute URI (an absolute URI without -- a fragment identifier). isAbsoluteURI :: String -> Bool -- | Test if string contains a valid relative URI (a relative URI with -- optional fragment identifier). isRelativeReference :: String -> Bool -- | Test if string contains a valid URI reference (an absolute or relative -- URI with optional fragment identifier). isURIReference :: String -> Bool -- | Test if string contains a valid URI (an absolute URI with optional -- fragment identifier). isURI :: String -> Bool -- | Parse an absolute URI to a URI value. Returns Nothing if -- the string is not a valid absolute URI. (an absolute URI without a -- fragment identifier). parseAbsoluteURI :: String -> Maybe URI -- | Parse a relative URI to a URI value. Returns Nothing if -- the string is not a valid relative URI. (a relative URI with optional -- fragment identifier). parseRelativeReference :: String -> Maybe URI -- | Parse a URI reference to a URI value. Returns Nothing if -- the string is not a valid URI reference. (an absolute or relative URI -- with optional fragment identifier). parseURIReference :: String -> Maybe URI -- | Turn a string containing a URI into a URI. Returns -- Nothing if the string is not a valid URI; (an absolute URI with -- optional fragment identifier). -- -- NOTE: this is different from the previous network.URI, whose -- parseURI function works like parseURIReference in this -- module. parseURI :: String -> Maybe URI -- | Blank URI nullURI :: URI -- | Type for authority value within a URI data URIAuth URIAuth :: String -> String -> String -> URIAuth -- |
--   anonymous@
--   
[uriUserInfo] :: URIAuth -> String -- |
--   www.haskell.org
--   
[uriRegName] :: URIAuth -> String -- |
--   :42
--   
[uriPort] :: URIAuth -> String -- | A variant of r that interprets the "|~]" sequence as -- "|]", "|~~]" as "|~]" and, in general, -- "|~^n]" as "|~^(n-1)]" for n >= 1. -- -- Usage: -- --
--   ghci> [rQ||~]|~]|]
--   "|]|]"
--   ghci> [rQ||~~]|]
--   "|~]"
--   ghci> [rQ||~~~~]|]
--   "|~~~]"
--   
rQ :: QuasiQuoter -- | A quasiquoter for raw string literals - that is, string literals that -- don't recognise the standard escape sequences (such as '\n'). -- Basically, they make your code more readable by freeing you from the -- responsibility to escape backslashes. They are useful when working -- with regular expressions, DOS/Windows paths and markup languages (such -- as XML). -- -- Don't forget the LANGUAGE QuasiQuotes pragma if you're using -- this module in your code. -- -- Usage: -- --
--   ghci> :set -XQuasiQuotes
--   ghci> import Text.RawString.QQ
--   ghci> let s = [r|\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}|]
--   ghci> s
--   "\\w+@[a-zA-Z_]+?\\.[a-zA-Z]{2,3}"
--   ghci> [r|C:\Windows\SYSTEM|] ++ [r|\user32.dll|]
--   "C:\\Windows\\SYSTEM\\user32.dll"
--   
-- -- Multiline raw string literals are also supported: -- --
--   multiline :: String
--   multiline = [r|<HTML>
--   <HEAD>
--   <TITLE>Auto-generated html formated source</TITLE>
--   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
--   </HEAD>
--   <BODY LINK="800080" BGCOLOR="#ffffff">
--   <P> </P>
--   <PRE>|]
--   
-- -- Caveat: since the "|]" character sequence is used to -- terminate the quasiquotation, you can't use it inside the raw string -- literal. Use rQ if you want to embed that character sequence -- inside the raw string. -- -- For more on raw strings, see e.g. -- http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2053.html -- -- For more on quasiquotation, see -- http://www.haskell.org/haskellwiki/Quasiquotation r :: QuasiQuoter -- | A handler for a RefineException. -- -- throwRefineOtherException is useful for defining what behaviour -- validate should have in the event of a predicate failure. throwRefineOtherException :: Monad m => TypeRep -> Doc Void -> RefineT m a -- | A handler function to handle previous RefineExceptions -- and return to normal execution. A common idiom is: -- --
--   do { action1; action2; action3 } `catchRefine' handler
--   
-- -- where the action functions can call throwRefine. Note -- that handler and the do-block must have the same return type. catchRefine :: Monad m => RefineT m a -> RefineException -> RefineT m a -> RefineT m a -- | One can use throwRefine inside of a monadic context to -- begin processing a RefineException. throwRefine :: Monad m => RefineException -> RefineT m a -- | Run a monadic action of type RefineM a, yielding an -- Either RefineException a. -- -- This is just defined as runIdentity . -- runRefineT. runRefineM :: () => RefineM a -> Either RefineException a -- | Constructs a computation in the RefineM monad. (The inverse of -- runRefineM). refineM :: () => Either RefineException a -> RefineM a -- | Map the unwrapped computation using the given function. -- --
--   runRefineT (mapRefineT f m) = f (runRefineT m)
--   
mapRefineT :: () => m Either RefineException a -> n Either RefineException b -> RefineT m a -> RefineT n b -- | The inverse of RefineT. runRefineT :: () => RefineT m a -> m Either RefineException a -- | Display a RefineException as a Doc ann displayRefineException :: () => RefineException -> Doc ann -- | This function helps type inference. It is equivalent to the following: -- --
--   instance Weaken r (Or l r)
--   
rightOr :: () => Refined r x -> Refined Or l r x -- | This function helps type inference. It is equivalent to the following: -- --
--   instance Weaken l (Or l r)
--   
leftOr :: () => Refined l x -> Refined Or l r x -- | This function helps type inference. It is equivalent to the following: -- --
--   instance Weaken (And l r) r
--   
andRight :: () => Refined And l r x -> Refined r x -- | This function helps type inference. It is equivalent to the following: -- --
--   instance Weaken (And l r) l
--   
andLeft :: () => Refined And l r x -> Refined l x -- | Extracts the refined value. unrefine :: () => Refined p x -> x -- | Constructs a Refined value at compile-time using -- -XTemplateHaskell. -- -- For example: -- --
--   >>> $$(refineTH 23) :: Refined Positive Int
--   Refined 23
--   
-- -- Here's an example of an invalid value: -- --
--   >>> $$(refineTH 0) :: Refined Positive Int
--   <interactive>:6:4:
--       Value is not greater than 0
--       In the Template Haskell splice $$(refineTH 0)
--       In the expression: $$(refineTH 0) :: Refined Positive Int
--       In an equation for ‘it’:
--           it = $$(refineTH 0) :: Refined Positive Int
--   
-- -- If it's not evident, the example above indicates a compile-time -- failure, which means that the checking was done at compile-time, thus -- introducing a zero runtime overhead compared to a plain value -- construction. refineTH :: (Predicate p x, Lift x) => x -> Q TExp Refined p x -- | Constructs a Refined value at run-time, calling error if -- the value does not satisfy the predicate. -- -- WARNING: this function is not total! unsafeRefine :: Predicate p x => x -> Refined p x -- | Constructs a Refined value at run-time, calling -- throwError if the value does not satisfy the predicate. refineError :: (Predicate p x, MonadError RefineException m) => x -> m Refined p x -- | Constructs a Refined value at run-time, calling fail if -- the value does not satisfy the predicate. refineFail :: (Predicate p x, MonadFail m) => x -> m Refined p x -- | Constructs a Refined value at run-time, calling throwM -- if the value does not satisfy the predicate. refineThrow :: (Predicate p x, MonadThrow m) => x -> m Refined p x -- | A smart constructor of a Refined value. Checks the input value -- at runtime. refine :: Predicate p x => x -> Either RefineException Refined p x -- | A refinement type, which wraps a value of type x, ensuring -- that it satisfies a type-level predicate p. -- -- The only ways that this library provides to construct a value of type -- Refined are with the 'refine-' family of functions, because the -- use of the newtype constructor gets around the checking of the -- predicate. This restriction on the user makes unrefine safe. -- -- If you would really like to construct a Refined value -- without checking the predicate, use unsafeCoerce. data Refined p x -- | A typeclass which defines a runtime interpretation of a type-level -- predicate p for type x. class Typeable p => Predicate p x -- | Check the value x according to the predicate p, -- producing an error string if the value does not satisfy. validate :: (Predicate p x, Monad m) => p -> x -> RefineT m () -- | The negation of a predicate. data Not p -- | The conjunction of two predicates. data And l r -- | The conjunction of two predicates. type && = And -- | The disjunction of two predicates. data Or l r -- | The disjunction of two predicates. type || = Or -- | A Predicate ensuring that the Foldable has a length -- which is less than the specified type-level number. data SizeLessThan (n :: Nat) -- | A Predicate ensuring that the Foldable has a length -- which is greater than the specified type-level number. data SizeGreaterThan (n :: Nat) -- | A Predicate ensuring that the Foldable has a length -- which is equal to the specified type-level number. data SizeEqualTo (n :: Nat) -- | A Predicate ensuring that the IsList contains elements -- in a strictly ascending order. data Ascending -- | A Predicate ensuring that the IsList contains elements -- in a strictly descending order. data Descending -- | A Predicate ensuring that the value is less than the specified -- type-level number. data LessThan (n :: Nat) -- | A Predicate ensuring that the value is greater than the -- specified type-level number. data GreaterThan (n :: Nat) -- | A Predicate ensuring that the value is greater than or equal to -- the specified type-level number. data From (n :: Nat) -- | A Predicate ensuring that the value is less than or equal to -- the specified type-level number. data To (n :: Nat) -- | A Predicate ensuring that the value is within an inclusive -- range. data FromTo (mn :: Nat) (mx :: Nat) -- | A Predicate ensuring that the value is equal to the specified -- type-level number n. data EqualTo (n :: Nat) -- | A Predicate ensuring that the value is not equal to the -- specified type-level number n. data NotEqualTo (n :: Nat) -- | A Predicate ensuring that the value is greater than zero. type Positive = GreaterThan 0 -- | A Predicate ensuring that the value is less than or equal to -- zero. type NonPositive = To 0 -- | A Predicate ensuring that the value is less than zero. type Negative = LessThan 0 -- | A Predicate ensuring that the value is greater than or equal to -- zero. type NonNegative = From 0 -- | An inclusive range of values from zero to one. type ZeroToOne = FromTo 0 1 -- | A Predicate ensuring that the value is not equal to zero. type NonZero = NotEqualTo 0 -- | A Predicate ensuring that the Foldable is non-empty. type NonEmpty = SizeGreaterThan 0 -- | A typeclass containing "safe" conversions between refined predicates -- where the target is weaker than the source: that is, all values -- that satisfy the first predicate will be guarunteed to satisy the -- second. -- -- Take care: writing an instance declaration for your custom predicates -- is the same as an assertion that weaken is safe to use: -- --
--   instance Weaken Pred1 Pred2
--   
-- -- For most of the instances, explicit type annotations for the result -- value's type might be required. class Weaken from to weaken :: Weaken from to => Refined from x -> Refined to x -- | An exception encoding the way in which a Predicate failed. data RefineException -- | A RefineException for failures involving the Not -- predicate. RefineNotException :: !TypeRep -> RefineException -- | A RefineException for failures involving the And -- predicate. RefineAndException :: !TypeRep -> !These RefineException RefineException -> RefineException -- | A RefineException for failures involving the Or -- predicate. RefineOrException :: !TypeRep -> !RefineException -> !RefineException -> RefineException -- | A RefineException for failures involving all other predicates. RefineOtherException :: !TypeRep -> !Doc Void -> RefineException -- | A monad transformer that adds RefineExceptions to -- other monads. -- -- The pure and return functions yield -- computations that produce the given value, while -- >>= sequences two subcomputations, exiting on -- the first RefineException. data RefineT (m :: * -> *) a -- | RefineM a is equivalent to RefineT -- Identity a for any type a. type RefineM a = RefineT Identity a -- | Lifted newChan. newChan :: MonadIO m => m Chan a -- | Lifted writeChan. writeChan :: MonadIO m => Chan a -> a -> m () -- | Lifted readChan. readChan :: MonadIO m => Chan a -> m a -- | Lifted dupChan. dupChan :: MonadIO m => Chan a -> m Chan a -- | Lifted getChanContents. getChanContents :: MonadIO m => Chan a -> m [a] -- | Lifted writeList2Chan. writeList2Chan :: MonadIO m => Chan a -> [a] -> m () -- | Exception type thrown by throwString. -- -- Note that the second field of the data constructor depends on GHC/base -- version. For base 4.9 and GHC 8.0 and later, the second field is a -- call stack. Previous versions of GHC and base do not support call -- stacks, and the field is simply unit (provided to make pattern -- matching across GHC versions easier). data StringException StringException :: String -> CallStack -> StringException -- | Wrap up a synchronous exception to be treated as an asynchronous -- exception. -- -- This is intended to be created via toAsyncException. data AsyncExceptionWrapper [AsyncExceptionWrapper] :: AsyncExceptionWrapper -- | Wrap up an asynchronous exception to be treated as a synchronous -- exception. -- -- This is intended to be created via toSyncException. data SyncExceptionWrapper [SyncExceptionWrapper] :: SyncExceptionWrapper -- | Unlifted catch, but will not catch asynchronous exceptions. catch :: (MonadUnliftIO m, Exception e) => m a -> e -> m a -> m a -- | catch specialized to only catching IOExceptions. catchIO :: MonadUnliftIO m => m a -> IOException -> m a -> m a -- | catch specialized to catch all synchronous exception. catchAny :: MonadUnliftIO m => m a -> SomeException -> m a -> m a -- | Same as catch, but fully force evaluation of the result value -- to find all impure exceptions. catchDeep :: (MonadUnliftIO m, Exception e, NFData a) => m a -> e -> m a -> m a -- | catchDeep specialized to catch all synchronous exception. catchAnyDeep :: (NFData a, MonadUnliftIO m) => m a -> SomeException -> m a -> m a -- | catchJust is like catch but it takes an extra argument -- which is an exception predicate, a function which selects which type -- of exceptions we're interested in. catchJust :: (MonadUnliftIO m, Exception e) => e -> Maybe b -> m a -> b -> m a -> m a -- | Flipped version of catch. handle :: (MonadUnliftIO m, Exception e) => e -> m a -> m a -> m a -- | handle specialized to only catching IOExceptions. handleIO :: MonadUnliftIO m => IOException -> m a -> m a -> m a -- | Flipped version of catchAny. handleAny :: MonadUnliftIO m => SomeException -> m a -> m a -> m a -- | Flipped version of catchDeep. handleDeep :: (MonadUnliftIO m, Exception e, NFData a) => e -> m a -> m a -> m a -- | Flipped version of catchAnyDeep. handleAnyDeep :: (MonadUnliftIO m, NFData a) => SomeException -> m a -> m a -> m a -- | Flipped catchJust. handleJust :: (MonadUnliftIO m, Exception e) => e -> Maybe b -> b -> m a -> m a -> m a -- | Unlifted try, but will not catch asynchronous exceptions. try :: (MonadUnliftIO m, Exception e) => m a -> m Either e a -- | try specialized to only catching IOExceptions. tryIO :: MonadUnliftIO m => m a -> m Either IOException a -- | try specialized to catch all synchronous exceptions. tryAny :: MonadUnliftIO m => m a -> m Either SomeException a -- | Same as try, but fully force evaluation of the result value to -- find all impure exceptions. tryDeep :: (MonadUnliftIO m, Exception e, NFData a) => m a -> m Either e a -- | tryDeep specialized to catch all synchronous exceptions. tryAnyDeep :: (MonadUnliftIO m, NFData a) => m a -> m Either SomeException a -- | A variant of try that takes an exception predicate to select -- which exceptions are caught. tryJust :: (MonadUnliftIO m, Exception e) => e -> Maybe b -> m a -> m Either b a -- | Evaluate the value to WHNF and catch any synchronous exceptions. -- -- The expression may still have bottom values within it; you may instead -- want to use pureTryDeep. pureTry :: () => a -> Either SomeException a -- | Evaluate the value to NF and catch any synchronous exceptions. pureTryDeep :: NFData a => a -> Either SomeException a -- | Same as upstream catches, but will not catch asynchronous -- exceptions. catches :: MonadUnliftIO m => m a -> [Handler m a] -> m a -- | Same as catches, but fully force evaluation of the result value -- to find all impure exceptions. catchesDeep :: (MonadUnliftIO m, NFData a) => m a -> [Handler m a] -> m a -- | Lifted version of evaluate. evaluate :: MonadIO m => a -> m a -- | Deeply evaluate a value using evaluate and NFData. evaluateDeep :: (MonadIO m, NFData a) => a -> m a -- | Async safe version of bracket. bracket :: MonadUnliftIO m => m a -> a -> m b -> a -> m c -> m c -- | Async safe version of bracket_. bracket_ :: MonadUnliftIO m => m a -> m b -> m c -> m c -- | Async safe version of bracketOnError. bracketOnError :: MonadUnliftIO m => m a -> a -> m b -> a -> m c -> m c -- | A variant of bracketOnError where the return value from the -- first computation is not required. bracketOnError_ :: MonadUnliftIO m => m a -> m b -> m c -> m c -- | Async safe version of finally. finally :: MonadUnliftIO m => m a -> m b -> m a -- | Like onException, but provides the handler the thrown -- exception. withException :: (MonadUnliftIO m, Exception e) => m a -> e -> m b -> m a -- | Async safe version of onException. onException :: MonadUnliftIO m => m a -> m b -> m a -- | Synchronously throw the given exception. throwIO :: (MonadIO m, Exception e) => e -> m a -- | Convert an exception into a synchronous exception. -- -- For synchronous exceptions, this is the same as toException. -- For asynchronous exceptions, this will wrap up the exception with -- SyncExceptionWrapper. toSyncException :: Exception e => e -> SomeException -- | Convert an exception into an asynchronous exception. -- -- For asynchronous exceptions, this is the same as toException. -- For synchronous exceptions, this will wrap up the exception with -- AsyncExceptionWrapper. toAsyncException :: Exception e => e -> SomeException -- | Check if the given exception is synchronous. isSyncException :: Exception e => e -> Bool -- | Check if the given exception is asynchronous. isAsyncException :: Exception e => e -> Bool -- | Unlifted version of mask. mask :: MonadUnliftIO m => forall a. () => m a -> m a -> m b -> m b -- | Unlifted version of uninterruptibleMask. uninterruptibleMask :: MonadUnliftIO m => forall a. () => m a -> m a -> m b -> m b -- | Unlifted version of mask_. mask_ :: MonadUnliftIO m => m a -> m a -- | Unlifted version of uninterruptibleMask_. uninterruptibleMask_ :: MonadUnliftIO m => m a -> m a -- | A convenience function for throwing a user error. This is useful for -- cases where it would be too high a burden to define your own exception -- type. -- -- This throws an exception of type StringException. When GHC -- supports it (base 4.9 and GHC 8.0 and onward), it includes a call -- stack. throwString :: (MonadIO m, HasCallStack) => String -> m a -- | Smart constructor for a StringException that deals with the -- call stack. stringException :: HasCallStack -> String -> StringException -- | Throw an asynchronous exception to another thread. -- -- Synchronously typed exceptions will be wrapped into an -- AsyncExceptionWrapper, see -- https://github.com/fpco/safe-exceptions#determining-sync-vs-async. -- -- It's usually a better idea to use the UnliftIO.Async module, -- see https://github.com/fpco/safe-exceptions#quickstart. throwTo :: (Exception e, MonadIO m) => ThreadId -> e -> m () -- | Generate a pure value which, when forced, will synchronously throw the -- given exception. -- -- Generally it's better to avoid using this function and instead use -- throwIO, see -- https://github.com/fpco/safe-exceptions#quickstart. impureThrow :: Exception e => e -> a -- | Unwrap an Either value, throwing its Left value as a -- runtime exception via throwIO if present. fromEither :: (Exception e, MonadIO m) => Either e a -> m a -- | Same as fromEither, but works on an IO-wrapped -- Either. fromEitherIO :: (Exception e, MonadIO m) => IO Either e a -> m a -- | Same as fromEither, but works on an m-wrapped -- Either. fromEitherM :: (Exception e, MonadIO m) => m Either e a -> m a -- | Lifted newEmptyMVar. newEmptyMVar :: MonadIO m => m MVar a -- | Lifted newMVar. newMVar :: MonadIO m => a -> m MVar a -- | Lifted takeMVar. takeMVar :: MonadIO m => MVar a -> m a -- | Lifted putMVar. putMVar :: MonadIO m => MVar a -> a -> m () -- | Lifted readMVar. readMVar :: MonadIO m => MVar a -> m a -- | Lifted swapMVar. swapMVar :: MonadIO m => MVar a -> a -> m a -- | Lifted tryTakeMVar. tryTakeMVar :: MonadIO m => MVar a -> m Maybe a -- | Lifted tryPutMVar. tryPutMVar :: MonadIO m => MVar a -> a -> m Bool -- | Lifted isEmptyMVar. isEmptyMVar :: MonadIO m => MVar a -> m Bool -- | Lifted tryReadMVar. tryReadMVar :: MonadIO m => MVar a -> m Maybe a -- | Unlifted withMVar. withMVar :: MonadUnliftIO m => MVar a -> a -> m b -> m b -- | Unlifted withMVarMasked. withMVarMasked :: MonadUnliftIO m => MVar a -> a -> m b -> m b -- | Unlifted modifyMVar_. modifyMVar_ :: MonadUnliftIO m => MVar a -> a -> m a -> m () -- | Unlifted modifyMVar. modifyMVar :: MonadUnliftIO m => MVar a -> a -> m (a, b) -> m b -- | Unlifted modifyMVarMasked_. modifyMVarMasked_ :: MonadUnliftIO m => MVar a -> a -> m a -> m () -- | Unlifted modifyMVarMasked. modifyMVarMasked :: MonadUnliftIO m => MVar a -> a -> m (a, b) -> m b -- | Unlifted mkWeakMVar. mkWeakMVar :: MonadUnliftIO m => MVar a -> m () -> m Weak MVar a -- | The Reader+IO monad. This is different from a ReaderT because: -- -- data RIO env a -- | Lifted version of myThreadId. myThreadId :: MonadIO m => m ThreadId -- | Lifted version of threadDelay. threadDelay :: MonadIO m => Int -> m () -- | Lifted version of threadWaitRead. threadWaitRead :: MonadIO m => Fd -> m () -- | Lifted version of threadWaitWrite. threadWaitWrite :: MonadIO m => Fd -> m () -- | Lifted version of isCurrentThreadBound. isCurrentThreadBound :: MonadIO m => m Bool -- | More general version of allFieldLinks. allFieldLinks' :: (HasLink ToServantApi routes, GenericServant routes AsLink a, ToServant routes AsLink a ~ MkLink ToServantApi routes a) => Link -> a -> routes AsLink a -- | Get all links as a record. allFieldLinks :: (HasLink ToServantApi routes, GenericServant routes AsLink Link, ToServant routes AsLink Link ~ MkLink ToServantApi routes Link) => routes AsLink Link -- | More general version of fieldLink fieldLink' :: (IsElem endpoint ToServantApi routes, HasLink endpoint, GenericServant routes AsApi) => Link -> a -> routes AsApi -> endpoint -> MkLink endpoint a -- | Given an API record field, create a link for that route. Only the -- field's type is used. -- --
--   data Record route = Record
--       { _get :: route :- Capture "id" Int :> Get '[JSON] String
--       , _put :: route :- ReqBody '[JSON] Int :> Put '[JSON] Bool
--       }
--     deriving (Generic)
--   
--   getLink :: Int -> Link
--   getLink = fieldLink _get
--   
fieldLink :: (IsElem endpoint ToServantApi routes, HasLink endpoint, GenericServant routes AsApi) => routes AsApi -> endpoint -> MkLink endpoint Link -- | More general allLinks. See safeLink'. allLinks' :: HasLink api => Link -> a -> Proxy api -> MkLink api a -- | Create all links in an API. -- -- Note that the api type must be restricted to the endpoints -- that have valid links to them. -- --
--   >>> type API = "foo" :> Capture "name" Text :> Get '[JSON] Text :<|> "bar" :> Capture "name" Int :> Get '[JSON] Double
--   
--   >>> let fooLink :<|> barLink = allLinks (Proxy :: Proxy API)
--   
--   >>> :t fooLink
--   fooLink :: Text -> Link
--   
--   >>> :t barLink
--   barLink :: Int -> Link
--   
-- -- Note: nested APIs don't work well with this approach -- --
--   >>> :kind! MkLink (Capture "nest" Char :> (Capture "x" Int :> Get '[JSON] Int :<|> Capture "y" Double :> Get '[JSON] Double)) Link
--   MkLink (Capture "nest" Char :> (Capture "x" Int :> Get '[JSON] Int :<|> Capture "y" Double :> Get '[JSON] Double)) Link :: *
--   = Char -> (Int -> Link) :<|> (Double -> Link)
--   
allLinks :: HasLink api => Proxy api -> MkLink api Link -- | More general safeLink. safeLink' :: (IsElem endpoint api, HasLink endpoint) => Link -> a -> Proxy api -> Proxy endpoint -> MkLink endpoint a -- | Create a valid (by construction) relative URI with query params. -- -- This function will only typecheck if endpoint is part of the -- API api safeLink :: (IsElem endpoint api, HasLink endpoint) => Proxy api -> Proxy endpoint -> MkLink endpoint Link -- | Configurable linkURI. -- --
--   >>> type API = "sum" :> QueryParams "x" Int :> Get '[JSON] Int
--   
--   >>> linkURI' LinkArrayElementBracket $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API) [1, 2, 3]
--   sum?x[]=1&x[]=2&x[]=3
--   
-- --
--   >>> linkURI' LinkArrayElementPlain $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API) [1, 2, 3]
--   sum?x=1&x=2&x=3
--   
linkURI' :: LinkArrayElementStyle -> Link -> URI -- | Transform Link into URI. -- --
--   >>> type API = "something" :> Get '[JSON] Int
--   
--   >>> linkURI $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API)
--   something
--   
-- --
--   >>> type API = "sum" :> QueryParams "x" Int :> Get '[JSON] Int
--   
--   >>> linkURI $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API) [1, 2, 3]
--   sum?x[]=1&x[]=2&x[]=3
--   
-- --
--   >>> type API = "foo/bar" :> Get '[JSON] Int
--   
--   >>> linkURI $ safeLink (Proxy :: Proxy API) (Proxy :: Proxy API)
--   foo%2Fbar
--   
-- --
--   >>> type SomeRoute = "abc" :> Capture "email" String :> Put '[JSON] ()
--   
--   >>> let someRoute = Proxy :: Proxy SomeRoute
--   
--   >>> safeLink someRoute someRoute "test@example.com"
--   Link {_segments = ["abc","test%40example.com"], _queryParams = []}
--   
-- --
--   >>> linkURI $ safeLink someRoute someRoute "test@example.com"
--   abc/test%40example.com
--   
linkURI :: Link -> URI linkQueryParams :: Link -> [Param] linkSegments :: Link -> [String] -- | A safe link datatype. The only way of constructing a Link is -- using safeLink, which means any Link is guaranteed to be -- part of the mentioned API. data Link -- | Query parameter. data Param SingleParam :: String -> Text -> Param ArrayElemParam :: String -> Text -> Param FlagParam :: String -> Param -- | How to encode array query elements. data LinkArrayElementStyle -- |
--   foo[]=1&foo[]=2
--   
LinkArrayElementBracket :: LinkArrayElementStyle -- |
--   foo=1&foo=2
--   
LinkArrayElementPlain :: LinkArrayElementStyle -- | A type that specifies that an API record contains a set of links. data AsLink a -- | Construct a toLink for an endpoint. class HasLink (endpoint :: k) where { type family MkLink (endpoint :: k) a :: *; } toLink :: HasLink endpoint => Link -> a -> Proxy endpoint -> Link -> MkLink endpoint a -- | WithNamedContext names a specific tagged context to use for the -- combinators in the API. (See also in servant-server, -- Servant.Server.Context.) For example: -- --
--   type UseNamedContextAPI = WithNamedContext "myContext" '[String] (
--       ReqBody '[JSON] Int :> Get '[JSON] Int)
--   
-- -- Both the ReqBody and Get combinators will use the -- WithNamedContext with type tag "myContext" as their context. -- -- Contexts are only relevant for servant-server. -- -- For more information, see the tutorial. data WithNamedContext (name :: Symbol) (subContext :: [*]) subApi -- | Flatten API into a list of endpoints. -- --
--   >>> Refl :: Endpoints SampleAPI :~: '["hello" :> Verb 'GET 200 '[JSON] Int, "bye" :> (Capture "name" String :> Verb 'POST 200 '[JSON, PlainText] Bool)]
--   Refl
--   
-- | You may use this type family to tell the type checker that your custom -- type may be skipped as part of a link. This is useful for things like -- QueryParam that are optional in a URI and do not -- affect them if they are omitted. -- --
--   >>> data CustomThing
--   
--   >>> type instance IsElem' e (CustomThing :> s) = IsElem e s
--   
-- -- Note that IsElem is called, which will mutually -- recurse back to IsElem' if it exhausts all other -- options again. -- -- Once you have written a HasLink instance for -- CustomThing you are ready to go. -- | Closed type family, check if endpoint is within api. -- Uses IsElem' if it exhausts all other options. -- --
--   >>> ok (Proxy :: Proxy (IsElem ("hello" :> Get '[JSON] Int) SampleAPI))
--   OK
--   
-- --
--   >>> ok (Proxy :: Proxy (IsElem ("bye" :> Get '[JSON] Int) SampleAPI))
--   ...
--   ... Could not deduce...
--   ...
--   
-- -- An endpoint is considered within an api even if it is missing -- combinators that don't affect the URL: -- --
--   >>> ok (Proxy :: Proxy (IsElem (Get '[JSON] Int) (Header "h" Bool :> Get '[JSON] Int)))
--   OK
--   
-- --
--   >>> ok (Proxy :: Proxy (IsElem (Get '[JSON] Int) (ReqBody '[JSON] Bool :> Get '[JSON] Int)))
--   OK
--   
-- -- -- | Check whether sub is a sub-API of api. -- --
--   >>> ok (Proxy :: Proxy (IsSubAPI SampleAPI (SampleAPI :<|> Get '[JSON] Int)))
--   OK
--   
-- --
--   >>> ok (Proxy :: Proxy (IsSubAPI (SampleAPI :<|> Get '[JSON] Int) SampleAPI))
--   ...
--   ... Could not deduce...
--   ...
--   
-- -- This uses IsElem for checking; thus the note there applies -- here. -- | Check that every element of xs is an endpoint of api -- (using IsElem). -- | Closed type family, check if endpoint is exactly within -- api. -- --
--   >>> ok (Proxy :: Proxy (IsIn ("hello" :> Get '[JSON] Int) SampleAPI))
--   OK
--   
-- -- Unlike IsElem, this requires an *exact* match. -- --
--   >>> ok (Proxy :: Proxy (IsIn (Get '[JSON] Int) (Header "h" Bool :> Get '[JSON] Int)))
--   ...
--   ... Could not deduce...
--   ...
--   
-- | Check whether sub is a sub API of api. -- -- Like IsSubAPI, but uses IsIn rather than IsElem. -- | Check that every element of xs is an endpoint of api -- (using IsIn). -- -- ok (Proxy :: Proxy (AllIsIn (Endpoints SampleAPI) SampleAPI)) OK -- | Apply (e :>) to every API in xs. -- | Append two type-level lists. -- | Check that a value is an element of a list: -- --
--   >>> ok (Proxy :: Proxy (Elem Bool '[Int, Bool]))
--   OK
--   
-- --
--   >>> ok (Proxy :: Proxy (Elem String '[Int, Bool]))
--   ...
--   ... [Char]...'[Int, Bool...
--   ...
--   
type Elem (e :: t) (es :: [t]) = ElemGo e es es -- | Verb is a general type for representing HTTP verbs (a.k.a. -- methods). For convenience, type synonyms for each verb with a 200 -- response code are provided, but you are free to define your own: -- --
--   >>> type Post204 contentTypes a = Verb 'POST 204 contentTypes a
--   
data Verb (method :: k1) (statusCode :: Nat) (contentTypes :: [*]) a :: forall k1. () => k1 -> Nat -> [*] -> * -> * -- | GET with 200 status code. type Get = Verb GET 200 -- | POST with 200 status code. type Post = Verb POST 200 -- | PUT with 200 status code. type Put = Verb PUT 200 -- | DELETE with 200 status code. type Delete = Verb DELETE 200 -- | PATCH with 200 status code. type Patch = Verb PATCH 200 -- | POST with 201 status code. type PostCreated = Verb POST 201 -- | GET with 202 status code. type GetAccepted = Verb GET 202 -- | POST with 202 status code. type PostAccepted = Verb POST 202 -- | DELETE with 202 status code. type DeleteAccepted = Verb DELETE 202 -- | PATCH with 202 status code. type PatchAccepted = Verb PATCH 202 -- | PUT with 202 status code. type PutAccepted = Verb PUT 202 -- | GET with 203 status code. type GetNonAuthoritative = Verb GET 203 -- | POST with 203 status code. type PostNonAuthoritative = Verb POST 203 -- | DELETE with 203 status code. type DeleteNonAuthoritative = Verb DELETE 203 -- | PATCH with 203 status code. type PatchNonAuthoritative = Verb PATCH 203 -- | PUT with 203 status code. type PutNonAuthoritative = Verb PUT 203 -- | GET with 204 status code. type GetNoContent = Verb GET 204 -- | POST with 204 status code. type PostNoContent = Verb POST 204 -- | DELETE with 204 status code. type DeleteNoContent = Verb DELETE 204 -- | PATCH with 204 status code. type PatchNoContent = Verb PATCH 204 -- | PUT with 204 status code. type PutNoContent = Verb PUT 204 -- | GET with 205 status code. type GetResetContent = Verb GET 205 -- | POST with 205 status code. type PostResetContent = Verb POST 205 -- | GET with 206 status code. type GetPartialContent = Verb GET 206 class ReflectMethod (a :: k) reflectMethod :: ReflectMethod a => Proxy a -> Method -- | The contained API (second argument) can be found under ("/" ++ -- path) (path being the first argument). -- -- Example: -- --
--   >>> -- GET /hello/world
--   
--   >>> -- returning a JSON encoded World value
--   
--   >>> type MyApi = "hello" :> "world" :> Get '[JSON] World
--   
data (:>) (path :: k) a :: forall k. () => k -> * -> * -- | A Stream endpoint for a given method emits a stream of encoded values -- at a given Content-Type, delimited by a framing strategy. Stream -- endpoints always return response code 200 on success. Type synonyms -- are provided for standard methods. data Stream (method :: k1) (status :: Nat) framing contentType a :: forall k1. () => k1 -> Nat -> * -> * -> * -> * type StreamGet = Stream GET 200 type StreamPost = Stream POST 200 -- | Stream endpoints may be implemented as producing a -- StreamGenerator -- a function that itself takes two emit -- functions -- the first to be used on the first value the stream emits, -- and the second to be used on all subsequent values (to allow -- interspersed framing strategies such as comma separation). newtype StreamGenerator a StreamGenerator :: a -> IO () -> a -> IO () -> IO () -> StreamGenerator a [getStreamGenerator] :: StreamGenerator a -> a -> IO () -> a -> IO () -> IO () -- | ToStreamGenerator is intended to be implemented for types such as -- Conduit, Pipe, etc. By implementing this class, all such streaming -- abstractions can be used directly as endpoints. class ToStreamGenerator a b | a -> b toStreamGenerator :: ToStreamGenerator a b => a -> StreamGenerator b -- | Clients reading from streaming endpoints can be implemented as -- producing a ResultStream that captures the setup, takedown, -- and incremental logic for a read, being an IO continuation that takes -- a producer of Just either values or errors that terminates with a -- Nothing. newtype ResultStream a ResultStream :: forall b. () => IO Maybe Either String a -> IO b -> IO b -> ResultStream a -- | BuildFromStream is intended to be implemented for types such as -- Conduit, Pipe, etc. By implementing this class, all such streaming -- abstractions can be used directly on the client side for talking to -- streaming endpoints. class BuildFromStream a b buildFromStream :: BuildFromStream a b => ResultStream a -> b -- | The FramingRender class provides the logic for emitting a framing -- strategy. The strategy emits a header, followed by boundary-delimited -- data, and finally a termination character. For many strategies, some -- of these will just be empty bytestrings. class FramingRender (strategy :: k) (a :: k1) header :: FramingRender strategy a => Proxy strategy -> Proxy a -> ByteString boundary :: FramingRender strategy a => Proxy strategy -> Proxy a -> BoundaryStrategy trailer :: FramingRender strategy a => Proxy strategy -> Proxy a -> ByteString -- | The bracketing strategy generates things to precede and follow the -- content, as with netstrings. The intersperse strategy inserts -- seperators between things, as with newline framing. Finally, the -- general strategy performs an arbitrary rewrite on the content, to -- allow escaping rules and such. data BoundaryStrategy BoundaryStrategyBracket :: ByteString -> (ByteString, ByteString) -> BoundaryStrategy BoundaryStrategyIntersperse :: ByteString -> BoundaryStrategy BoundaryStrategyGeneral :: ByteString -> ByteString -> BoundaryStrategy -- | A type of parser that can never fail, and has different parsing -- strategies (incremental, or EOF) depending if more input can be sent. -- The incremental parser should return Nothing if it would like -- to be sent a longer ByteString. If it returns a value, it also returns -- the remainder following that value. data ByteStringParser a ByteStringParser :: ByteString -> Maybe (a, ByteString) -> ByteString -> (a, ByteString) -> ByteStringParser a [parseIncremental] :: ByteStringParser a -> ByteString -> Maybe (a, ByteString) [parseEOF] :: ByteStringParser a -> ByteString -> (a, ByteString) -- | The FramingUnrender class provides the logic for parsing a framing -- strategy. The outer ByteStringParser strips the header from a -- stream of bytes, and yields a parser that can handle the remainder, -- stepwise. Each frame may be a ByteString, or a String indicating the -- error state for that frame. Such states are per-frame, so that -- protocols that can resume after errors are able to do so. Eventually -- this returns an empty ByteString to indicate termination. class FramingUnrender (strategy :: k) (a :: k1) unrenderFrames :: FramingUnrender strategy a => Proxy strategy -> Proxy a -> ByteStringParser ByteStringParser Either String ByteString -- | A framing strategy that does not do any framing at all, it just passes -- the input data This will be used most of the time with binary data, -- such as files data NoFraming -- | A simple framing strategy that has no header or termination, and -- inserts a newline character between each frame. This assumes that it -- is used with a Content-Type that encodes without newlines (e.g. JSON). data NewlineFraming -- | The netstring framing strategy as defined by djb: -- http://cr.yp.to/proto/netstrings.txt data NetstringFraming -- | Deliberately do not add a header to a value. -- --
--   >>> let example1 = noHeader "hi" :: Headers '[Header "someheader" Int] String
--   
--   >>> getHeaders example1
--   []
--   
noHeader :: AddHeader h v orig new => orig -> new -- | addHeader adds a header to a response. Note that it changes -- the type of the value in the following ways: -- --
    --
  1. A simple value is wrapped in "Headers '[hdr]":
  2. --
-- --
--   >>> let example1 = addHeader 5 "hi" :: Headers '[Header "someheader" Int] String;
--   
--   >>> getHeaders example1
--   [("someheader","5")]
--   
-- --
    --
  1. A value that already has a header has its new header *prepended* -- to the existing list:
  2. --
-- --
--   >>> let example1 = addHeader 5 "hi" :: Headers '[Header "someheader" Int] String;
--   
--   >>> let example2 = addHeader True example1 :: Headers '[Header "1st" Bool, Header "someheader" Int] String
--   
--   >>> getHeaders example2
--   [("1st","true"),("someheader","5")]
--   
-- -- Note that while in your handlers type annotations are not required, -- since the type can be inferred from the API type, in other cases you -- may find yourself needing to add annotations. addHeader :: AddHeader h v orig new => v -> orig -> new -- | Response Header objects. You should never need to construct one -- directly. Instead, use addOptionalHeader. data Headers (ls :: [*]) a Headers :: a -> HList ls -> Headers a -- | The underlying value of a Headers [getResponse] :: Headers a -> a -- | HList of headers. [getHeadersHList] :: Headers a -> HList ls data ResponseHeader (sym :: Symbol) a Header :: a -> ResponseHeader a MissingHeader :: ResponseHeader a UndecodableHeader :: ByteString -> ResponseHeader a data HList (a :: [*]) [HNil] :: HList ([] :: [*]) [HCons] :: HList Header h x : xs class BuildHeadersTo (hs :: [*]) -- | Note: if there are multiple occurences of a header in the argument, -- the values are interspersed with commas before deserialization (see -- RFC2616 Sec 4.2) buildHeadersTo :: BuildHeadersTo hs => [Header] -> HList hs class GetHeaders ls getHeaders :: GetHeaders ls => ls -> [Header] class AddHeader (h :: Symbol) v orig new | h v orig -> new, new -> h, new -> v, new -> orig -- | Extract the request body as a value of type a. -- -- Example: -- --
--   >>> -- POST /books
--   
--   >>> type MyApi = "books" :> ReqBody '[JSON] Book :> Post '[JSON] Book
--   
type ReqBody = ReqBody' Required : Strict : ([] :: [*]) -- | Note: ReqBody' is always Required. data ReqBody' (mods :: [*]) (contentTypes :: [*]) a -- | Provides access to the host or IP address from which the HTTP request -- was sent. data RemoteHost -- | Endpoint for plugging in your own Wai Applications. -- -- The given Application will get the request as received by the -- server, potentially with a modified (stripped) pathInfo if -- the Application is being routed with :>. -- -- In addition to just letting you plug in your existing WAI -- Applications, this can also be used with -- serveDirectory to serve static files stored in a particular -- directory on your filesystem data Raw -- | Lookup the value associated to the sym query string parameter -- and try to extract it as a value of type a. -- -- Example: -- --
--   >>> -- /books?author=<author name>
--   
--   >>> type MyApi = "books" :> QueryParam "author" Text :> Get '[JSON] [Book]
--   
type QueryParam = QueryParam' Optional : Strict : ([] :: [*]) -- | QueryParam which can be Required, Lenient, or -- modified otherwise. data QueryParam' (mods :: [*]) (sym :: Symbol) a -- | Lookup the values associated to the sym query string -- parameter and try to extract it as a value of type [a]. This -- is typically meant to support query string parameters of the form -- param[]=val1&param[]=val2 and so on. Note that servant -- doesn't actually require the []s and will fetch the values -- just fine with param=val1&param=val2, too. -- -- Example: -- --
--   >>> -- /books?authors[]=<author1>&authors[]=<author2>&...
--   
--   >>> type MyApi = "books" :> QueryParams "authors" Text :> Get '[JSON] [Book]
--   
data QueryParams (sym :: Symbol) a -- | Lookup a potentially value-less query string parameter with boolean -- semantics. If the param sym is there without any value, or if -- it's there with value "true" or "1", it's interpreted as True. -- Otherwise, it's interpreted as False. -- -- Example: -- --
--   >>> -- /books?published
--   
--   >>> type MyApi = "books" :> QueryFlag "published" :> Get '[JSON] [Book]
--   
data QueryFlag (sym :: Symbol) -- | Extract the given header's value as a value of type a. I.e. -- header sent by client, parsed by server. -- -- Example: -- --
--   >>> newtype Referer = Referer Text deriving (Eq, Show)
--   
--   >>> 
--   
--   >>> -- GET /view-my-referer
--   
--   >>> type MyApi = "view-my-referer" :> Header "from" Referer :> Get '[JSON] Referer
--   
type Header = (Header' Optional : Strict : ([] :: [*]) :: Symbol -> k -> *) data Header' (mods :: [*]) (sym :: Symbol) (a :: k) :: forall k. () => [*] -> Symbol -> k -> * -- | Required argument. Not wrapped. data Required -- | Optional argument. Wrapped in Maybe. data Optional -- | Leniently parsed argument, i.e. parsing never fail. Wrapped in -- Either Text. data Lenient -- | Strictly parsed argument. Not wrapped. data Strict -- | Was this request made over an SSL connection? -- -- Note that this value will not tell you if the client originally made -- this request over SSL, but rather whether the current connection is -- SSL. The distinction lies with reverse proxies. In many cases, the -- client will connect to a load balancer over SSL, but connect to the -- WAI handler without SSL. In such a case, the handlers would get -- NotSecure, but from a user perspective, there is a secure -- connection. data IsSecure -- | the connection to the server is secure (HTTPS) Secure :: IsSecure -- | the connection to the server is not secure (HTTP) NotSecure :: IsSecure -- | A generalized Authentication combinator. Use this if you have a -- non-standard authentication technique. -- -- NOTE: THIS API IS EXPERIMENTAL AND SUBJECT TO CHANGE. data AuthProtect (tag :: k) :: forall k. () => k -> * -- | An empty API: one which serves nothing. Morally speaking, this should -- be the unit of :<|>. Implementors of interpretations of -- API types should treat EmptyAPI as close to the unit as -- possible. data EmptyAPI EmptyAPI :: EmptyAPI -- | Add a short summary for (part of) API. -- -- Example: -- --
--   >>> type MyApi = Summary "Get book by ISBN." :> "books" :> Capture "isbn" Text :> Get '[JSON] Book
--   
data Summary (sym :: Symbol) -- | Add more verbose description for (part of) API. -- -- Example: -- --
--   >>> :{
--   type MyApi = Description
--    "This comment is visible in multiple Servant interpretations \
--    \and can be really long if necessary. \
--    \Haskell multiline support is not perfect \
--    \but it's still very readable."
--   :> Get '[JSON] Book
--   :}
--   
data Description (sym :: Symbol) data JSON data PlainText data FormUrlEncoded data OctetStream -- | Instances of Accept represent mimetypes. They are used for -- matching against the Accept HTTP header of the request, and -- for setting the Content-Type header of the response -- -- Example: -- --
--   >>> import Network.HTTP.Media ((//), (/:))
--   
--   >>> data HTML
--   
--   >>> :{
--   instance Accept HTML where
--      contentType _ = "text" // "html" /: ("charset", "utf-8")
--   :}
--   
class Accept (ctype :: k) contentType :: Accept ctype => Proxy ctype -> MediaType contentTypes :: Accept ctype => Proxy ctype -> NonEmpty MediaType -- | Instantiate this class to register a way of serializing a type based -- on the Accept header. -- -- Example: -- --
--   data MyContentType
--   
--   instance Accept MyContentType where
--      contentType _ = "example" // "prs.me.mine" /: ("charset", "utf-8")
--   
--   instance Show a => MimeRender MyContentType a where
--      mimeRender _ val = pack ("This is MINE! " ++ show val)
--   
--   type MyAPI = "path" :> Get '[MyContentType] Int
--   
class Accept ctype => MimeRender (ctype :: k) a mimeRender :: MimeRender ctype a => Proxy ctype -> a -> ByteString -- | Instantiate this class to register a way of deserializing a type based -- on the request's Content-Type header. -- --
--   >>> import Network.HTTP.Media hiding (Accept)
--   
--   >>> import qualified Data.ByteString.Lazy.Char8 as BSC
--   
--   >>> data MyContentType = MyContentType String
--   
-- --
--   >>> :{
--   instance Accept MyContentType where
--      contentType _ = "example" // "prs.me.mine" /: ("charset", "utf-8")
--   :}
--   
-- --
--   >>> :{
--   instance Read a => MimeUnrender MyContentType a where
--      mimeUnrender _ bs = case BSC.take 12 bs of
--        "MyContentType" -> return . read . BSC.unpack $ BSC.drop 12 bs
--        _ -> Left "didn't start with the magic incantation"
--   :}
--   
-- --
--   >>> type MyAPI = "path" :> ReqBody '[MyContentType] Int :> Get '[JSON] Int
--   
class Accept ctype => MimeUnrender (ctype :: k) a mimeUnrender :: MimeUnrender ctype a => Proxy ctype -> ByteString -> Either String a -- | Variant which is given the actual MediaType provided by the -- other party. -- -- In the most cases you don't want to branch based on the -- MediaType. See pr552 for a motivating example. mimeUnrenderWithType :: MimeUnrender ctype a => Proxy ctype -> MediaType -> ByteString -> Either String a -- | A type for responses without content-body. data NoContent NoContent :: NoContent -- | Capture a value from the request path under a certain type a. -- -- Example: -- --
--   >>> -- GET /books/:isbn
--   
--   >>> type MyApi = "books" :> Capture "isbn" Text :> Get '[JSON] Book
--   
type Capture = Capture' ([] :: [*]) -- | Capture which can be modified. For example with -- Description. data Capture' (mods :: [*]) (sym :: Symbol) a -- | Capture all remaining values from the request path under a certain -- type a. -- -- Example: -- --
--   >>> -- GET /src/*
--   
--   >>> type MyAPI = "src" :> CaptureAll "segments" Text :> Get '[JSON] SourceFile
--   
data CaptureAll (sym :: Symbol) a -- | Combinator for Basic Access Authentication. -- -- -- -- In Basic Auth, username and password are base64-encoded and -- transmitted via the Authorization header. Handshakes are not -- required, making it relatively efficient. data BasicAuth (realm :: Symbol) userData -- | A simple datatype to hold data required to decorate a request data BasicAuthData BasicAuthData :: !ByteString -> !ByteString -> BasicAuthData [basicAuthUsername] :: BasicAuthData -> !ByteString [basicAuthPassword] :: BasicAuthData -> !ByteString -- | Union of two APIs, first takes precedence in case of overlap. -- -- Example: -- --
--   >>> :{
--   type MyApi = "books" :> Get '[JSON] [Book] -- GET /books
--          :<|> "books" :> ReqBody '[JSON] Book :> Post '[JSON] () -- POST /books
--   :}
--   
data (:<|>) a b (:<|>) :: a -> b -> (:<|>) a b -- | A persistent store for values of arbitrary types. -- -- This variant is the simplest and creates keys in the IO monad. -- See the module Data.Vault.ST if you want to use it with the -- ST monad instead. type Vault = Vault RealWorld class SBoolI (b :: Bool) sbool :: SBoolI b => SBool b data SBool (b :: Bool) [STrue] :: SBool True [SFalse] :: SBool False -- | Same as serveDirectoryFileServer. It used to be the only file -- serving function in servant pre-0.10 and will be kept around for a few -- versions, but is deprecated. serveDirectory :: () => FilePath -> ServerT Raw m -- | Alias for staticApp. Lets you serve a directory with arbitrary -- StaticSettings. Useful when you want particular settings not -- covered by the four other variants. This is the most flexible method. serveDirectoryWith :: () => StaticSettings -> ServerT Raw m -- | Uses embeddedSettings. serveDirectoryEmbedded :: () => [(FilePath, ByteString)] -> ServerT Raw m -- | Same as serveDirectoryWebApp, but uses -- webAppSettingsWithLookup. serveDirectoryWebAppLookup :: () => ETagLookup -> FilePath -> ServerT Raw m -- | Same as serveDirectoryWebApp, but uses -- defaultFileServerSettings. serveDirectoryFileServer :: () => FilePath -> ServerT Raw m -- | Serve anything under the specified directory as a Raw endpoint. -- --
--   type MyApi = "static" :> Raw
--   
--   server :: Server MyApi
--   server = serveDirectoryWebApp "/var/www"
--   
-- -- would capture any request to /static/<something> and -- look for <something> under /var/www. -- -- It will do its best to guess the MIME type for that file, based on the -- extension, and send an appropriate Content-Type header if -- possible. -- -- If your goal is to serve HTML, CSS and Javascript files that use the -- rest of the API as a webapp backend, you will most likely not want the -- static files to be hidden behind a /static/ prefix. In that -- case, remember to put the serveDirectoryWebApp handler in the -- last position, because servant will try to match the handlers -- in order. -- -- Corresponds to the defaultWebAppSettings StaticSettings -- value. serveDirectoryWebApp :: () => FilePath -> ServerT Raw m -- | Variant of layout that takes an additional Context. layoutWithContext :: HasServer api context => Proxy api -> Context context -> Text -- | The function layout produces a textual description of the -- internal router layout for debugging purposes. Note that the router -- layout is determined just by the API, not by the handlers. -- -- Example: -- -- For the following API -- --
--   type API =
--          "a" :> "d" :> Get '[JSON] NoContent
--     :<|> "b" :> Capture "x" Int :> Get '[JSON] Bool
--     :<|> "c" :> Put '[JSON] Bool
--     :<|> "a" :> "e" :> Get '[JSON] Int
--     :<|> "b" :> Capture "x" Int :> Put '[JSON] Bool
--     :<|> Raw
--   
-- -- we get the following output: -- --
--   /
--   ├─ a/
--   │  ├─ d/
--   │  │  └─•
--   │  └─ e/
--   │     └─•
--   ├─ b/
--   │  └─ <capture>/
--   │     ├─•
--   │     ┆
--   │     └─•
--   ├─ c/
--   │  └─•
--   ┆
--   └─ <raw>
--   
-- -- Explanation of symbols: -- -- layout :: HasServer api ([] :: [*]) => Proxy api -> Text -- | Hoist server implementation. -- -- Sometimes our cherished Handler monad isn't quite the type -- you'd like for your handlers. Maybe you want to thread some -- configuration in a Reader monad. Or have your types ensure -- that your handlers don't do any IO. Use hoistServer (a -- successor of now deprecated enter). -- -- With hoistServer, you can provide a function, to convert any -- number of endpoints from one type constructor to another. For example -- -- Note: Server Raw can also be entered. It will -- be retagged. -- --
--   >>> import Control.Monad.Reader
--   
--   >>> type ReaderAPI = "ep1" :> Get '[JSON] Int :<|> "ep2" :> Get '[JSON] String :<|> Raw :<|> EmptyAPI
--   
--   >>> let readerApi = Proxy :: Proxy ReaderAPI
--   
--   >>> let readerServer = return 1797 :<|> ask :<|> Tagged (error "raw server") :<|> emptyServer :: ServerT ReaderAPI (Reader String)
--   
--   >>> let nt x = return (runReader x "hi")
--   
--   >>> let mainServer = hoistServer readerApi nt readerServer :: Server ReaderAPI
--   
hoistServer :: HasServer api ([] :: [*]) => Proxy api -> forall x. () => m x -> n x -> ServerT api m -> ServerT api n serveWithContext :: HasServer api context => Proxy api -> Context context -> Server api -> Application -- | serve allows you to implement an API and produce a wai -- Application. -- -- Example: -- --
--   type MyApi = "books" :> Get '[JSON] [Book] -- GET /books
--           :<|> "books" :> ReqBody Book :> Post '[JSON] Book -- POST /books
--   
--   server :: Server MyApi
--   server = listAllBooks :<|> postBook
--     where listAllBooks = ...
--           postBook book = ...
--   
--   myApi :: Proxy MyApi
--   myApi = Proxy
--   
--   app :: Application
--   app = serve myApi server
--   
--   main :: IO ()
--   main = Network.Wai.Handler.Warp.run 8080 app
--   
serve :: HasServer api ([] :: [*]) => Proxy api -> Server api -> Application -- | Server for EmptyAPI emptyServer :: () => ServerT EmptyAPI m class HasServer (api :: k) (context :: [*]) where { type family ServerT (api :: k) (m :: * -> *) :: *; } route :: HasServer api context => Proxy api -> Context context -> Delayed env Server api -> Router env hoistServerWithContext :: HasServer api context => Proxy api -> Proxy context -> forall x. () => m x -> n x -> ServerT api m -> ServerT api n type Server (api :: k) = ServerT api Handler -- | Singleton type representing a server that serves an empty API. data EmptyServer -- | servant-server's current implementation of basic authentication is not -- immune to certian kinds of timing attacks. Decoding payloads does not -- take a fixed amount of time. -- -- The result of authentication/authorization data BasicAuthResult usr Unauthorized :: BasicAuthResult usr BadPassword :: BasicAuthResult usr NoSuchUser :: BasicAuthResult usr Authorized :: usr -> BasicAuthResult usr -- | Datatype wrapping a function used to check authentication. newtype BasicAuthCheck usr BasicAuthCheck :: BasicAuthData -> IO BasicAuthResult usr -> BasicAuthCheck usr [unBasicAuthCheck] :: BasicAuthCheck usr -> BasicAuthData -> IO BasicAuthResult usr -- | Apply a transformation to the response of a Router. tweakResponse :: () => RouteResult Response -> RouteResult Response -> Router env -> Router env toApplication :: RoutingApplication -> Application runHandler :: () => Handler a -> IO Either ServantErr a runHandler' :: Handler a -> ExceptT ServantErr IO a -- | err505 HTTP Version not supported -- -- Example usage: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err505 { errBody = "I support HTTP/4.0 only." }
--   
err505 :: ServantErr -- | err504 Gateway Time-out -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err504 { errBody = "Backend foobar did not respond in 5 seconds." }
--   
err504 :: ServantErr -- | err503 Service Unavailable -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err503 { errBody = "We're rewriting in PHP." }
--   
err503 :: ServantErr -- | err502 Bad Gateway -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err502 { errBody = "Tried gateway foo, bar, and baz.  None responded." }
--   
err502 :: ServantErr -- | err501 Not Implemented -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err501 { errBody = "/v1/foo is not supported with quux in the request." }
--   
err501 :: ServantErr -- | err500 Internal Server Error -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err500 { errBody = "Exception in module A.B.C:55.  Have a great day!" }
--   
err500 :: ServantErr -- | err422 Unprocessable Entity -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err422 { errBody = "I understood your request, but can't process it." }
--   
err422 :: ServantErr -- | err418 Expectation Failed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err418 { errBody = "Apologies, this is not a webserver but a teapot." }
--   
err418 :: ServantErr -- | err417 Expectation Failed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err417 { errBody = "I found a quux in the request.  This isn't going to work." }
--   
err417 :: ServantErr -- | err416 Request range not satisfiable -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err416 { errBody = "Valid range is [0, 424242]." }
--   
err416 :: ServantErr -- | err415 Unsupported Media Type -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err415 { errBody = "Supported media types:  gif, png" }
--   
err415 :: ServantErr -- | err414 Request-URI Too Large -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err414 { errBody = "Maximum length is 64." }
--   
err414 :: ServantErr -- | err413 Request Entity Too Large -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err413 { errBody = "Request exceeded 64k." }
--   
err413 :: ServantErr -- | err412 Precondition Failed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err412 { errBody = "Precondition fail: x < 42 && y > 57" }
--   
err412 :: ServantErr -- | err411 Length Required -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err411
--   
err411 :: ServantErr -- | err410 Gone -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err410 { errBody = "I know it was here at some point, but.. I blame bad luck." }
--   
err410 :: ServantErr -- | err409 Conflict -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err409 { errBody = "Transaction conflicts with 59879cb56c7c159231eeacdd503d755f7e835f74" }
--   
err409 :: ServantErr -- | err407 Proxy Authentication Required -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err407
--   
err407 :: ServantErr -- | err406 Not Acceptable -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err406
--   
err406 :: ServantErr -- | err405 Method Not Allowed -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err405 { errBody = "Your account privileges does not allow for this.  Please pay $$$." }
--   
err405 :: ServantErr -- | err404 Not Found -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err404 { errBody = "(╯°□°)╯︵ ┻━┻)." }
--   
err404 :: ServantErr -- | err403 Forbidden -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err403 { errBody = "Please login first." }
--   
err403 :: ServantErr -- | err402 Payment Required -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err402 { errBody = "You have 0 credits. Please give me $$$." }
--   
err402 :: ServantErr -- | err401 Unauthorized -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err401 { errBody = "Your credentials are invalid." }
--   
err401 :: ServantErr -- | err400 Bad Request -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err400 { errBody = "Your request makes no sense to me." }
--   
err400 :: ServantErr -- | err307 Temporary Redirect -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err307
--   
err307 :: ServantErr -- | err305 Use Proxy -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err305
--   
err305 :: ServantErr -- | err304 Not Modified -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err304
--   
err304 :: ServantErr -- | err303 See Other -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err303
--   
err303 :: ServantErr -- | err302 Found -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err302
--   
err302 :: ServantErr -- | err301 Moved Permanently -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError err301
--   
err301 :: ServantErr -- | err300 Multiple Choices -- -- Example: -- --
--   failingHandler :: Handler ()
--   failingHandler = throwError $ err300 { errBody = "I can't choose." }
--   
err300 :: ServantErr data ServantErr ServantErr :: Int -> String -> ByteString -> [Header] -> ServantErr [errHTTPCode] :: ServantErr -> Int [errReasonPhrase] :: ServantErr -> String [errBody] :: ServantErr -> ByteString [errHeaders] :: ServantErr -> [Header] -- | descendIntoNamedContext allows you to access -- NamedContexts. Usually you won't have to use it yourself but -- instead use a combinator like WithNamedContext. -- -- This is how descendIntoNamedContext works: -- --
--   >>> :set -XFlexibleContexts
--   
--   >>> let subContext = True :. EmptyContext
--   
--   >>> :type subContext
--   subContext :: Context '[Bool]
--   
--   >>> let parentContext = False :. (NamedContext subContext :: NamedContext "subContext" '[Bool]) :. EmptyContext
--   
--   >>> :type parentContext
--   parentContext :: Context '[Bool, NamedContext "subContext" '[Bool]]
--   
--   >>> descendIntoNamedContext (Proxy :: Proxy "subContext") parentContext :: Context '[Bool]
--   True :. EmptyContext
--   
descendIntoNamedContext :: HasContextEntry context NamedContext name subContext => Proxy name -> Context context -> Context subContext -- | Contexts are used to pass values to combinators. (They are -- not meant to be used to pass parameters to your handlers, i.e. -- they should not replace any custom ReaderT-monad-stack that -- you're using with hoistServer.) If you don't use combinators -- that require any context entries, you can just use serve as -- always. -- -- If you are using combinators that require a non-empty Context -- you have to use serveWithContext and pass it a Context -- that contains all the values your combinators need. A Context -- is essentially a heterogenous list and accessing the elements is being -- done by type (see getContextEntry). The parameter of the type -- Context is a type-level list reflecting the types of the -- contained context entries. To create a Context with entries, -- use the operator (:.): -- --
--   >>> :type True :. () :. EmptyContext
--   True :. () :. EmptyContext :: Context '[Bool, ()]
--   
data Context (contextTypes :: [*]) [EmptyContext] :: Context ([] :: [*]) [:.] :: Context x : xs -- | This class is used to access context entries in Contexts. -- getContextEntry returns the first value where the type matches: -- --
--   >>> getContextEntry (True :. False :. EmptyContext) :: Bool
--   True
--   
-- -- If the Context does not contain an entry of the requested type, -- you'll get an error: -- --
--   >>> getContextEntry (True :. False :. EmptyContext) :: String
--   ...
--   ...No instance for (HasContextEntry '[] [Char])
--   ...
--   
class HasContextEntry (context :: [*]) val getContextEntry :: HasContextEntry context val => Context context -> val -- | Normally context entries are accessed by their types. In case you need -- to have multiple values of the same type in your Context and -- need to access them, we provide NamedContext. You can think of -- it as sub-namespaces for Contexts. data NamedContext (name :: Symbol) (subContext :: [*]) NamedContext :: Context subContext -> NamedContext -- | The WAI application. -- -- Note that, since WAI 3.0, this type is structured in continuation -- passing style to allow for proper safe resource handling. This was -- handled in the past via other means (e.g., ResourceT). As a -- demonstration: -- --
--   app :: Application
--   app req respond = bracket_
--       (putStrLn "Allocating scarce resource")
--       (putStrLn "Cleaning up")
--       (respond $ responseLBS status200 [] "Hello World")
--   
type Application = Request -> Response -> IO ResponseReceived -> IO ResponseReceived -- | A Tagged s b value is a value b with an -- attached phantom type s. This can be used in place of the -- more traditional but less safe idiom of passing in an undefined value -- with the type, because unlike an (s -> b), a -- Tagged s b can't try to use the argument s as -- a real value. -- -- Moreover, you don't have to rely on the compiler to inline away the -- extra argument, because the newtype is "free" -- -- Tagged has kind k -> * -> * if the compiler -- supports PolyKinds, therefore there is an extra k -- showing in the instance haddocks that may cause confusion. newtype Tagged (s :: k) b :: forall k. () => k -> * -> * Tagged :: b -> Tagged b [unTagged] :: Tagged b -> b -- | Split on the given sublist. Equivalent to split . -- dropDelims . onSublist. For example: -- --
--   splitOn ".." "a..b...c....d.." == ["a","b",".c","","d",""]
--   
-- -- In some parsing combinator frameworks this is also known as -- sepBy. -- -- Note that this is the right inverse of the intercalate function -- from Data.List, that is, -- --
--   intercalate x . splitOn x === id
--   
-- -- splitOn x . intercalate x is the identity on -- certain lists, but it is tricky to state the precise conditions under -- which this holds. (For example, it is not enough to say that -- x does not occur in any elements of the input list. Working -- out why is left as an exercise for the reader.) splitOn :: Eq a => [a] -> [a] -> [[a]] fromLT :: ConvertibleStrings LT a => LT -> a fromLazyText :: ConvertibleStrings LazyText a => LazyText -> a fromST :: ConvertibleStrings ST a => ST -> a fromStrictText :: ConvertibleStrings StrictText a => StrictText -> a fromLBS :: ConvertibleStrings LBS a => LBS -> a fromLazyByteString :: ConvertibleStrings LazyByteString a => LazyByteString -> a fromSBS :: ConvertibleStrings SBS a => SBS -> a fromStrictByteString :: ConvertibleStrings StrictByteString a => StrictByteString -> a toLT :: ConvertibleStrings a LT => a -> LT toLazyText :: ConvertibleStrings a LazyText => a -> LazyText toST :: ConvertibleStrings a ST => a -> ST toStrictText :: ConvertibleStrings a StrictText => a -> StrictText toLBS :: ConvertibleStrings a LBS => a -> LBS toLazyByteString :: ConvertibleStrings a LazyByteString => a -> LazyByteString toSBS :: ConvertibleStrings a SBS => a -> SBS toStrictByteString :: ConvertibleStrings a StrictByteString => a -> StrictByteString toString :: ConvertibleStrings a String => a -> String cs :: ConvertibleStrings a b => a -> b class ConvertibleStrings a b convertString :: ConvertibleStrings a b => a -> b type StrictByteString = ByteString type SBS = ByteString type LazyByteString = ByteString type LBS = ByteString type StrictText = Text type ST = Text type LazyText = Text type LT = Text -- | Convert a ExceptT computation to MaybeT, discarding the -- value of any exception. exceptToMaybeT :: Functor m => ExceptT e m a -> MaybeT m a -- | Convert a MaybeT computation to ExceptT, with a default -- exception value. maybeToExceptT :: Functor m => e -> MaybeT m a -> ExceptT e m a -- | Lifted version of mkWeakThreadId. mkWeakThreadId :: MonadIO m => ThreadId -> m Weak ThreadId -- | Unlifted version of runInUnboundThread. runInUnboundThread :: MonadUnliftIO m => m a -> m a -- | Unlifted version of runInBoundThread. runInBoundThread :: MonadUnliftIO m => m a -> m a -- | Unflifted version of forkOS. forkOS :: MonadUnliftIO m => m () -> m ThreadId -- | Lifted version of yield. yield :: MonadIO m => m () -- | Lifted version of threadCapability. threadCapability :: MonadIO m => ThreadId -> m (Int, Bool) -- | Lifted version of setNumCapabilities. setNumCapabilities :: MonadIO m => Int -> m () -- | Lifted version of getNumCapabilities. getNumCapabilities :: MonadIO m => m Int -- | Unlifted version of forkOnWithUnmask. forkOnWithUnmask :: MonadUnliftIO m => Int -> forall a. () => m a -> m a -> m () -> m ThreadId -- | Unlifted version of forkOn. forkOn :: MonadUnliftIO m => Int -> m () -> m ThreadId -- | Lifted version of killThread. killThread :: MonadIO m => ThreadId -> m () -- | Unlifted version of forkFinally. forkFinally :: MonadUnliftIO m => m a -> Either SomeException a -> m () -> m ThreadId -- | Unlifted version of forkIOWithUnmask. forkWithUnmask :: MonadUnliftIO m => forall a. () => m a -> m a -> m () -> m ThreadId -- | Unlifted version of forkIO. forkIO :: MonadUnliftIO m => m () -> m ThreadId -- | Middleware is a component that sits between the server and -- application. It can do such tasks as GZIP encoding or response -- caching. What follows is the general definition of middleware, though -- a middleware author should feel free to modify this. -- -- As an example of an alternate type for middleware, suppose you write a -- function to load up session information. The session information is -- simply a string map <math>. A logical type signature for this -- middleware might be: -- --
--   loadSession :: ([(String, String)] -> Application) -> Application
--   
-- -- Here, instead of taking a standard Application as its first -- argument, the middleware takes a function which consumes the session -- information as well. type Middleware = Application -> Application defWaiMain :: Application -> IO () defPutListening :: WaiOptions -> IO () waiMain :: WaiOptions -> IO () -> WaiOptions -> IO () -> Application -> IO () runGraceful :: GracefulMode -> Settings -> Application -> IO () -> Settings -> Application -> IO () runActivated :: Settings -> Socket -> Application -> IO () -> Settings -> Application -> IO () data GracefulMode ServeNormally :: GracefulMode Serve503 :: GracefulMode data WaiOptions WaiOptions :: Int -> String -> String -> String -> String -> String -> Maybe Bool -> WaiOptions -- | Create a middleware to be added to a WAI-based webserver. metrics :: WaiMetrics -> Middleware -- | Register in EKG a number of metrics related to web server activity -- with a namespace. -- -- registerNamedWaiMetrics :: Text -> Store -> IO WaiMetrics -- | Register in EKG a number of metrics related to web server activity -- using empty namespace. -- -- registerWaiMetrics :: Store -> IO WaiMetrics -- | The metrics to feed in WAI and register in EKG. data WaiMetrics WaiMetrics :: Counter -> Distribution -> Counter -> Counter -> Counter -> Counter -> Counter -> WaiMetrics [requestCounter] :: WaiMetrics -> Counter [latencyDistribution] :: WaiMetrics -> Distribution [statusCode100Counter] :: WaiMetrics -> Counter [statusCode200Counter] :: WaiMetrics -> Counter [statusCode300Counter] :: WaiMetrics -> Counter [statusCode400Counter] :: WaiMetrics -> Counter [statusCode500Counter] :: WaiMetrics -> Counter runMagicbaneHandler :: β -> RIO β α -> Handler α -- | Constructs a WAI application from an API definition, a Servant context -- (used for auth mainly), the app context and the actual action -- handlers. magicbaneApp :: forall β χ ψ. (HasServer χ ψ) => Proxy χ -> Context ψ -> β -> ServerT χ (RIO β) -> Application type Formatter = TimedFastLogger -> CallStack -> LogSource -> LogLevel -> Utf8Builder -> IO () type ModLogger = LogFunc -- | Creates a logger module using a given formatting function. | Also -- returns the underlying TimedFastLogger for use outside of your -- Magicbane app (e.g. in some WAI middleware). newLogger :: LogType -> Formatter -> IO (TimedFastLogger, ModLogger) simpleFormatter :: Formatter newtype ModMetrics ModMetrics :: Metrics -> ModMetrics forkMetricsServer :: ByteString -> Int -> IO Server -- | Creates a metrics module with a particular Store. The Store should -- come from the backend you want to use for storing the metrics. For -- development, a simple backend that shows metrics on a web page is -- ekg-wai, reexported here. newMetricsWith :: Store -> IO ModMetrics type WithLink α = (Headers '[Header "Link" [HTTPLink]] α) type HTTPLink = Link type Form = ReqBody '[FormUrlEncoded] [(Text, Text)] type Host = Header "Host" Text hPutStrLn :: MonadIO μ => Handle -> String -> μ () -- | Merges two JSON objects recursively. When the values are not objects, -- just returns the left one. mergeVal :: Value -> Value -> Value -- | Encodes key-value data as application/x-www-form-urlencoded. writeForm :: (ConvertibleStrings α Text, ConvertibleStrings β Text, ConvertibleStrings ByteString γ) => [(α, β)] -> γ -- | Decodes key-value data from application/x-www-form-urlencoded. readForm :: (ConvertibleStrings Text α, ConvertibleStrings Text β, ConvertibleStrings γ ByteString) => γ -> Maybe [(α, β)] -- | Reads a Servant incoming form as a list of key-value pairs (for use in -- FromForm instances). formList :: Form -> [(Text, Text)] -- | Converts a flat key-value form with keys in typical nesting syntax -- (e.g. "one[two][three]") to an Aeson Value with nesting (for use in -- FromForm instances). formToObject :: [(Text, Text)] -> Value formKey :: Parser [Text] -- | Parses any string into a URI. parseUri :: ConvertibleStrings α String => α -> URI -- | Prepares text for inclusion in a URL. -- --
--   >>> :set -XOverloadedStrings
--   
--   >>> slugify "Hello & World!"
--   "hello-and-world"
--   
slugify :: Text -> Text -- | Creates a simple text/plain ServantErr. errText :: ServantErr -> ByteString -> ServantErr -- | Creates and throws a simple text/plain ServantErr. throwErrText :: MonadThrow μ => ServantErr -> ByteString -> μ α type MonadHTTP ψ μ = (HasHttpManager ψ, MonadReader ψ μ, MonadUnliftIO μ) newtype ModHttpClient ModHttpClient :: Manager -> ModHttpClient newHttpClient :: IO ModHttpClient runHTTP :: ExceptT ε μ α -> μ (Either ε α) -- | Creates a request from a URI. reqU :: (MonadHTTP ψ μ) => URI -> ExceptT Text μ Request -- | Creates a request from a string of any type, parsing it into a URI. reqS :: (MonadHTTP ψ μ, ConvertibleStrings σ String) => σ -> ExceptT Text μ Request -- | Configures the request to not throw errors on error status codes. anyStatus :: (MonadHTTP ψ μ) => Request -> ExceptT Text μ Request -- | Sets a x-www-form-urlencoded form as the request body (also sets the -- content-type). postForm :: (MonadHTTP ψ μ) => [(Text, Text)] -> Request -> ExceptT Text μ Request -- | Sets a JSON value as the request body (via ToJSON; also sets the -- content-type). postJson :: (MonadHTTP ψ μ, ToJSON α) => α -> Request -> ExceptT Text μ Request -- | Performs the request, using a given function to read the body. This is -- what all other performWith functions are based on. performWithFn :: (MonadHTTP ψ μ, MonadCatch μ) => (ConduitM ι ByteString μ () -> ConduitT () Void μ ρ) -> Request -> ExceptT Text μ (Response ρ) -- | Performs the request, ignoring the body. performWithVoid :: (MonadHTTP ψ μ, MonadCatch μ) => Request -> ExceptT Text μ (Response ()) -- | Performs the request, reading the body into a lazy ByteString. performWithBytes :: (MonadHTTP ψ μ, MonadCatch μ) => Request -> ExceptT Text μ (Response ByteString) -- | Add headers to the request, preserving any existing headers not -- specified in the new set. applyHeaders :: RequestHeaders -> Request -> Request -- | Remove listed headers from the request. removeHeaders :: [HeaderName] -> Request -> Request -- | Gets a value of any type from the context. askObj :: (Has β α, MonadReader α μ) => μ β -- | Gets a thing from a value of any type from the context. (Useful for -- configuration fields.) askOpt :: (Has β α, MonadReader α μ) => (β -> ψ) -> μ ψ decodeEnvy :: FromEnv a => IO Maybe a -- | Reads an Envy configuration from the env variables and launches the -- given action if successful. (Does environment variable reading ever -- fail in practice? Probably not.) withEnvConfig :: FromEnv α => (α -> IO ()) -> IO () type BasicApp α = RIO BasicContext α type BasicContext = (ModHttpClient, ModLogger) newBasicContext :: IO BasicContext