-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Helpers for generating clients for servant APIs in any programming language
--   
--   Helper types and functions for generating client functions for servant
--   APIs in any programming language
--   
--   This package provides types and functions that collect all the data
--   needed to generate client functions in the programming language of
--   your choice. This effectively means you only have to write the code
--   that "pretty-prints" this data as some code in your target language.
--   
--   See the servant-js package for an example
--   
--   <a>CHANGELOG</a>
@package servant-foreign
@version 0.15.4

module Servant.Foreign.Internal

-- | Canonical name of the endpoint, can be used to generate a function
--   name.
--   
--   You can use the functions in <a>Servant.Foreign.Inflections</a>, like
--   <a>camelCase</a> to transform to <a>ErrorMessage</a>.
newtype FunctionName
FunctionName :: [Text] -> FunctionName
[unFunctionName] :: FunctionName -> [Text]
_FunctionName :: Iso' FunctionName [Text]

-- | See documentation of <a>Arg</a>
newtype PathSegment
PathSegment :: Text -> PathSegment
[unPathSegment] :: PathSegment -> Text
_PathSegment :: Iso' PathSegment Text

-- | Maps a name to the foreign type that belongs to the annotated value.
--   
--   Used for header args, query args, and capture args.
data Arg ftype
Arg :: PathSegment -> ftype -> Arg ftype

-- | The name to be captured.
--   
--   Only for capture args it really denotes a path segment.
[_argName] :: Arg ftype -> PathSegment

-- | Foreign type the associated value will have
[_argType] :: Arg ftype -> ftype
argType :: forall ftype_a9Qc ftype_abPZ. Lens (Arg ftype_a9Qc) (Arg ftype_abPZ) ftype_a9Qc ftype_abPZ
argName :: forall ftype_a9Qc. Lens' (Arg ftype_a9Qc) PathSegment
argPath :: Getter (Arg ftype) Text
data SegmentType ftype

-- | Static path segment.
--   
--   <pre>
--   "foo/bar/baz"
--   </pre>
--   
--   contains the static segments <tt>"foo"</tt>, <tt>"bar"</tt> and
--   <tt>"baz"</tt>.
Static :: PathSegment -> SegmentType ftype

-- | A capture.
--   
--   <pre>
--   "user/{userid}/name"
--   </pre>
--   
--   would capture the arg <tt>userid</tt> with type <tt>ftype</tt>.
Cap :: Arg ftype -> SegmentType ftype
_Cap :: forall ftype_ac27 ftype_abQe. Prism (SegmentType ftype_ac27) (SegmentType ftype_abQe) (Arg ftype_ac27) (Arg ftype_abQe)
_Static :: forall ftype_abQe. Prism' (SegmentType ftype_abQe) PathSegment

-- | A part of the Url’s path.
newtype Segment ftype
Segment :: SegmentType ftype -> Segment ftype
[unSegment] :: Segment ftype -> SegmentType ftype
_Segment :: forall ftype_acg3 ftype_ac2h. Iso (Segment ftype_acg3) (Segment ftype_ac2h) (SegmentType ftype_acg3) (SegmentType ftype_ac2h)

-- | Whether a segment is a <a>Cap</a>.
isCapture :: Segment ftype -> Bool

-- | Crashing Arg extraction from segment, TODO: remove
captureArg :: Segment ftype -> Arg ftype
type Path ftype = [Segment ftype]

-- | Type of a <a>QueryArg</a>.
data ArgType
Normal :: ArgType
Flag :: ArgType
List :: ArgType
_List :: Prism' ArgType ()
_Flag :: Prism' ArgType ()
_Normal :: Prism' ArgType ()

-- | Url Query argument.
--   
--   Urls can contain query arguments, which is a list of key-value pairs.
--   In a typical url, query arguments look like this:
--   
--   <pre>
--   ?foo=bar&amp;alist[]=el1&amp;alist[]=el2&amp;aflag
--   </pre>
--   
--   Each pair can be
--   
--   <ul>
--   <li><tt>?foo=bar</tt>: a plain key-val pair, either optional or
--   required (<a>QueryParam</a>)</li>
--   <li><tt>?aflag</tt>: a flag (no value, implicitly Bool with default
--   <tt>false</tt> if it’s missing) (<a>QueryFlag</a>)</li>
--   <li><tt>?alist[]=el1&amp;alist[]=el2</tt>: list of values
--   (<a>QueryParams</a>)</li>
--   </ul>
--   
--   <tt>_queryArgType</tt> will be set accordingly.
--   
--   For the plain key-val pairs (<a>QueryParam</a>),
--   <tt>_queryArgName</tt>’s <tt>ftype</tt> will be wrapped in a
--   <tt>Maybe</tt> if the argument is optional.
data QueryArg ftype
QueryArg :: Arg ftype -> ArgType -> QueryArg ftype

-- | Name and foreign type of the argument. Will be wrapped in <a>Maybe</a>
--   if the query is optional and in a `[]` if the query is a list
[_queryArgName] :: QueryArg ftype -> Arg ftype

-- | one of normal/plain, list or flag
[_queryArgType] :: QueryArg ftype -> ArgType
queryArgType :: forall ftype_acnI. Lens' (QueryArg ftype_acnI) ArgType
queryArgName :: forall ftype_acnI ftype_acD6. Lens (QueryArg ftype_acnI) (QueryArg ftype_acD6) (Arg ftype_acnI) (Arg ftype_acD6)
data HeaderArg ftype

-- | The name of the header and the foreign type of its value.
HeaderArg :: Arg ftype -> HeaderArg ftype
[_headerArg] :: HeaderArg ftype -> Arg ftype

-- | Unused, will never be set.
--   
--   TODO: remove
ReplaceHeaderArg :: Arg ftype -> Text -> HeaderArg ftype
[_headerArg] :: HeaderArg ftype -> Arg ftype
[_headerPattern] :: HeaderArg ftype -> Text
headerPattern :: forall ftype_acDm. Traversal' (HeaderArg ftype_acDm) Text
headerArg :: forall ftype_acDm ftype_acMF. Lens (HeaderArg ftype_acDm) (HeaderArg ftype_acMF) (Arg ftype_acDm) (Arg ftype_acMF)
_ReplaceHeaderArg :: forall ftype_acDm. Prism' (HeaderArg ftype_acDm) (Arg ftype_acDm, Text)
_HeaderArg :: forall ftype_acDm. Prism' (HeaderArg ftype_acDm) (Arg ftype_acDm)

-- | Full endpoint url, with all captures and parameters
data Url ftype
Url :: Path ftype -> [QueryArg ftype] -> Maybe ftype -> Url ftype

-- | Url path, list of either static segments or captures
--   
--   <pre>
--   "foo/{id}/bar"
--   </pre>
[_path] :: Url ftype -> Path ftype

-- | List of query args
--   
--   <pre>
--   "?foo=bar&amp;a=b"
--   </pre>
[_queryStr] :: Url ftype -> [QueryArg ftype]

-- | Url fragment.
--   
--   Not sent to the HTTP server, so only useful for frontend matters (e.g.
--   inter-page linking).
--   
--   <pre>
--   #fragmentText
--   </pre>
[_frag] :: Url ftype -> Maybe ftype
defUrl :: Url ftype
queryStr :: forall ftype_acOC. Lens' (Url ftype_acOC) [QueryArg ftype_acOC]
path :: forall ftype_acOC. Lens' (Url ftype_acOC) (Path ftype_acOC)
frag :: forall ftype_acOC. Lens' (Url ftype_acOC) (Maybe ftype_acOC)

-- | See documentation of <a>_reqBodyContentType</a>
data ReqBodyContentType
ReqBodyJSON :: ReqBodyContentType
ReqBodyMultipart :: ReqBodyContentType

-- | Full description of an endpoint in your API, generated by
--   <a>listFromAPI</a>. It should give you all the information needed to
--   generate foreign language bindings.
--   
--   Every field containing <tt>ftype</tt> will use the foreign type
--   mapping specified via <a>HasForeignType</a> (see its docstring on how
--   to set that up).
--   
--   See <a>https://docs.servant.dev/en/stable/tutorial/ApiType.html</a>
--   for accessible documentation of the possible content of an endpoint.
data Req ftype
Req :: Url ftype -> Method -> [HeaderArg ftype] -> Maybe ftype -> Maybe ftype -> FunctionName -> ReqBodyContentType -> Req ftype

-- | Full list of URL segments, including captures
[_reqUrl] :: Req ftype -> Url ftype

-- | <tt>"GET"</tt>/<tt>"POST"</tt>/<tt>"PUT"</tt>/…
[_reqMethod] :: Req ftype -> Method

-- | Headers required by this endpoint, with their type
[_reqHeaders] :: Req ftype -> [HeaderArg ftype]

-- | Foreign type of the expected request body (<a>ReqBody</a>), if any
[_reqBody] :: Req ftype -> Maybe ftype

-- | The foreign type of the response, if any
[_reqReturnType] :: Req ftype -> Maybe ftype

-- | The URL segments rendered in a way that they can be easily
--   concatenated into a canonical function name
[_reqFuncName] :: Req ftype -> FunctionName

-- | The content type the request body is transferred as.
--   
--   This is a severe limitation of <tt>servant-foreign</tt> currently, as
--   we only allow the content type to be <a>JSON</a> no user-defined
--   content types. (<a>ReqBodyMultipart</a> is not actually implemented.)
--   
--   Thus, any routes looking like this will work:
--   
--   <pre>
--   "foo" :&gt; Get '[JSON] Foo
--   </pre>
--   
--   while routes like
--   
--   <pre>
--   "foo" :&gt; Get '[MyFancyContentType] Foo
--   </pre>
--   
--   will fail with an error like
--   
--   <pre>
--   • JSON expected in list '[MyFancyContentType]
--   </pre>
[_reqBodyContentType] :: Req ftype -> ReqBodyContentType
reqUrl :: forall ftype_acZb. Lens' (Req ftype_acZb) (Url ftype_acZb)
reqReturnType :: forall ftype_acZb. Lens' (Req ftype_acZb) (Maybe ftype_acZb)
reqMethod :: forall ftype_acZb. Lens' (Req ftype_acZb) Method
reqHeaders :: forall ftype_acZb. Lens' (Req ftype_acZb) [HeaderArg ftype_acZb]
reqFuncName :: forall ftype_acZb. Lens' (Req ftype_acZb) FunctionName
reqBodyContentType :: forall ftype_acZb. Lens' (Req ftype_acZb) ReqBodyContentType
reqBody :: forall ftype_acZb. Lens' (Req ftype_acZb) (Maybe ftype_acZb)
defReq :: Req ftype

-- | <a>HasForeignType</a> maps Haskell types with types in the target
--   language of your backend. For example, let's say you're implementing a
--   backend to some language <b>X</b>, and you want a Text representation
--   of each input/output type mentioned in the API:
--   
--   <pre>
--   -- First you need to create a dummy type to parametrize your
--   -- instances.
--   data LangX
--   
--   -- Otherwise you define instances for the types you need
--   instance HasForeignType LangX Text Int where
--      typeFor _ _ _ = "intX"
--   
--   -- Or for example in case of lists
--   instance HasForeignType LangX Text a =&gt; HasForeignType LangX Text [a] where
--      typeFor lang type _ = "listX of " &lt;&gt; typeFor lang ftype (Proxy :: Proxy a)
--   </pre>
--   
--   Finally to generate list of information about all the endpoints for an
--   API you create a function of a form:
--   
--   <pre>
--   getEndpoints :: (HasForeign LangX Text api, GenerateList Text (Foreign Text api))
--                =&gt; Proxy api -&gt; [Req Text]
--   getEndpoints api = listFromAPI (Proxy :: Proxy LangX) (Proxy :: Proxy Text) api
--   </pre>
--   
--   <pre>
--   -- If language __X__ is dynamically typed then you can use
--   -- a predefined NoTypes parameter with the NoContent output type:
--   </pre>
--   
--   <pre>
--   getEndpoints :: (HasForeign NoTypes NoContent api, GenerateList Text (Foreign NoContent api))
--                =&gt; Proxy api -&gt; [Req NoContent]
--   getEndpoints api = listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy NoContent) api
--   </pre>
class HasForeignType lang ftype a
typeFor :: HasForeignType lang ftype a => Proxy lang -> Proxy ftype -> Proxy a -> ftype

-- | The language definition without any foreign types. It can be used for
--   dynamic languages which do not <i>do</i> type annotations.
data NoTypes

-- | Implementation of the Servant framework types.
--   
--   Relevant instances: Everything containing <a>HasForeignType</a>.
class HasForeign lang ftype (api :: *) where {
    type Foreign ftype api :: *;
}
foreignFor :: HasForeign lang ftype api => Proxy lang -> Proxy ftype -> Proxy api -> Req ftype -> Foreign ftype api
data EmptyForeignAPI
EmptyForeignAPI :: EmptyForeignAPI

-- | Utility class used by <a>listFromAPI</a> which computes the data
--   needed to generate a function for each endpoint and hands it all back
--   in a list.
class GenerateList ftype reqs
generateList :: GenerateList ftype reqs => reqs -> [Req ftype]

-- | Generate the necessary data for codegen as a list, each <a>Req</a>
--   describing one endpoint from your API type.
listFromAPI :: (HasForeign lang ftype api, GenerateList ftype (Foreign ftype api)) => Proxy lang -> Proxy ftype -> Proxy api -> [Req ftype]
instance Servant.Foreign.Internal.GenerateList ftype Servant.Foreign.Internal.EmptyForeignAPI
instance Servant.Foreign.Internal.GenerateList ftype (Servant.Foreign.Internal.Req ftype)
instance (Servant.Foreign.Internal.GenerateList ftype start, Servant.Foreign.Internal.GenerateList ftype rest) => Servant.Foreign.Internal.GenerateList ftype (start Servant.API.Alternative.:<|> rest)
instance forall k (lang :: k) ftype. Servant.Foreign.Internal.HasForeign lang ftype Servant.API.Empty.EmptyAPI
instance forall k (lang :: k) ftype a b. (Servant.Foreign.Internal.HasForeign lang ftype a, Servant.Foreign.Internal.HasForeign lang ftype b) => Servant.Foreign.Internal.HasForeign lang ftype (a Servant.API.Alternative.:<|> b)
instance forall k (sym :: GHC.Types.Symbol) (lang :: k) ftype t api (mods :: [*]). (GHC.TypeLits.KnownSymbol sym, Servant.Foreign.Internal.HasForeignType lang ftype t, Servant.Foreign.Internal.HasForeign lang ftype api) => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.Capture.Capture' mods sym t Servant.API.Sub.:> api)
instance forall k (sym :: GHC.Types.Symbol) (lang :: k) ftype t sublayout. (GHC.TypeLits.KnownSymbol sym, Servant.Foreign.Internal.HasForeignType lang ftype [t], Servant.Foreign.Internal.HasForeign lang ftype sublayout) => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.Capture.CaptureAll sym t Servant.API.Sub.:> sublayout)
instance forall k k1 (list :: [*]) (lang :: k) ftype a (method :: k1) (status :: GHC.TypeNats.Nat). (Servant.API.TypeLevel.Elem Servant.API.ContentTypes.JSON list, Servant.Foreign.Internal.HasForeignType lang ftype a, Servant.API.Verbs.ReflectMethod method) => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.Verbs.Verb method status list a)
instance forall k k1 (lang :: k) ftype (method :: k1). (Servant.Foreign.Internal.HasForeignType lang ftype Servant.API.ContentTypes.NoContent, Servant.API.Verbs.ReflectMethod method) => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.Verbs.NoContentVerb method)
instance forall k k1 ct (lang :: k) ftype a (method :: k1) (status :: GHC.TypeNats.Nat) framing. (ct GHC.Types.~ Servant.API.ContentTypes.JSON, Servant.Foreign.Internal.HasForeignType lang ftype a, Servant.API.Verbs.ReflectMethod method) => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.Stream.Stream method status framing ct a)
instance forall k (sym :: GHC.Types.Symbol) (lang :: k) ftype (mods :: [*]) a api. (GHC.TypeLits.KnownSymbol sym, Servant.Foreign.Internal.HasForeignType lang ftype (Servant.API.Modifiers.RequiredArgument mods a), Servant.Foreign.Internal.HasForeign lang ftype api) => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.Header.Header' mods sym a Servant.API.Sub.:> api)
instance forall k (sym :: GHC.Types.Symbol) (lang :: k) ftype (mods :: [*]) a api. (GHC.TypeLits.KnownSymbol sym, Servant.Foreign.Internal.HasForeignType lang ftype (Servant.API.Modifiers.RequiredArgument mods a), Servant.Foreign.Internal.HasForeign lang ftype api) => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.QueryParam.QueryParam' mods sym a Servant.API.Sub.:> api)
instance forall k (sym :: GHC.Types.Symbol) (lang :: k) ftype a api. (GHC.TypeLits.KnownSymbol sym, Servant.Foreign.Internal.HasForeignType lang ftype [a], Servant.Foreign.Internal.HasForeign lang ftype api) => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.QueryParam.QueryParams sym a Servant.API.Sub.:> api)
instance forall k (sym :: GHC.Types.Symbol) (lang :: k) ftype api. (GHC.TypeLits.KnownSymbol sym, Servant.Foreign.Internal.HasForeignType lang ftype GHC.Types.Bool, Servant.Foreign.Internal.HasForeign lang ftype api) => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.QueryParam.QueryFlag sym Servant.API.Sub.:> api)
instance forall k (lang :: k) ftype a api. (Servant.Foreign.Internal.HasForeignType lang ftype (GHC.Maybe.Maybe a), Servant.Foreign.Internal.HasForeign lang ftype api) => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.Fragment.Fragment a Servant.API.Sub.:> api)
instance forall k (lang :: k) ftype. Servant.Foreign.Internal.HasForeign lang ftype Servant.API.Raw.Raw
instance forall k (list :: [*]) (lang :: k) ftype a api (mods :: [*]). (Servant.API.TypeLevel.Elem Servant.API.ContentTypes.JSON list, Servant.Foreign.Internal.HasForeignType lang ftype a, Servant.Foreign.Internal.HasForeign lang ftype api) => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.ReqBody.ReqBody' mods list a Servant.API.Sub.:> api)
instance forall k (lang :: k) ftype api (mods :: [*]) framing ctype a. Servant.Foreign.Internal.HasForeign lang ftype api => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.Stream.StreamBody' mods framing ctype a Servant.API.Sub.:> api)
instance forall k (path :: GHC.Types.Symbol) (lang :: k) ftype api. (GHC.TypeLits.KnownSymbol path, Servant.Foreign.Internal.HasForeign lang ftype api) => Servant.Foreign.Internal.HasForeign lang ftype (path Servant.API.Sub.:> api)
instance forall k (lang :: k) ftype api. Servant.Foreign.Internal.HasForeign lang ftype api => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.RemoteHost.RemoteHost Servant.API.Sub.:> api)
instance forall k (lang :: k) ftype api. Servant.Foreign.Internal.HasForeign lang ftype api => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.IsSecure.IsSecure Servant.API.Sub.:> api)
instance forall k (lang :: k) ftype api. Servant.Foreign.Internal.HasForeign lang ftype api => Servant.Foreign.Internal.HasForeign lang ftype (Data.Vault.Lazy.Vault Servant.API.Sub.:> api)
instance forall k (lang :: k) ftype api (name :: GHC.Types.Symbol) (context :: [*]). Servant.Foreign.Internal.HasForeign lang ftype api => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.WithNamedContext.WithNamedContext name context api)
instance forall k (lang :: k) ftype api. Servant.Foreign.Internal.HasForeign lang ftype api => Servant.Foreign.Internal.HasForeign lang ftype (Network.HTTP.Types.Version.HttpVersion Servant.API.Sub.:> api)
instance forall k (lang :: k) ftype api (desc :: GHC.Types.Symbol). Servant.Foreign.Internal.HasForeign lang ftype api => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.Description.Summary desc Servant.API.Sub.:> api)
instance forall k (lang :: k) ftype api (desc :: GHC.Types.Symbol). Servant.Foreign.Internal.HasForeign lang ftype api => Servant.Foreign.Internal.HasForeign lang ftype (Servant.API.Description.Description desc Servant.API.Sub.:> api)
instance forall k (a :: k). Servant.Foreign.Internal.HasForeignType Servant.Foreign.Internal.NoTypes Servant.API.ContentTypes.NoContent a
instance GHC.Read.Read Servant.Foreign.Internal.ReqBodyContentType
instance GHC.Show.Show Servant.Foreign.Internal.ReqBodyContentType
instance GHC.Classes.Eq Servant.Foreign.Internal.ReqBodyContentType
instance Data.Data.Data Servant.Foreign.Internal.ReqBodyContentType
instance GHC.Show.Show ftype => GHC.Show.Show (Servant.Foreign.Internal.Req ftype)
instance GHC.Classes.Eq ftype => GHC.Classes.Eq (Servant.Foreign.Internal.Req ftype)
instance Data.Data.Data ftype => Data.Data.Data (Servant.Foreign.Internal.Req ftype)
instance GHC.Show.Show ftype => GHC.Show.Show (Servant.Foreign.Internal.Url ftype)
instance GHC.Classes.Eq ftype => GHC.Classes.Eq (Servant.Foreign.Internal.Url ftype)
instance Data.Data.Data ftype => Data.Data.Data (Servant.Foreign.Internal.Url ftype)
instance GHC.Show.Show ftype => GHC.Show.Show (Servant.Foreign.Internal.HeaderArg ftype)
instance GHC.Classes.Eq ftype => GHC.Classes.Eq (Servant.Foreign.Internal.HeaderArg ftype)
instance Data.Data.Data ftype => Data.Data.Data (Servant.Foreign.Internal.HeaderArg ftype)
instance GHC.Show.Show ftype => GHC.Show.Show (Servant.Foreign.Internal.QueryArg ftype)
instance GHC.Classes.Eq ftype => GHC.Classes.Eq (Servant.Foreign.Internal.QueryArg ftype)
instance Data.Data.Data ftype => Data.Data.Data (Servant.Foreign.Internal.QueryArg ftype)
instance GHC.Show.Show Servant.Foreign.Internal.ArgType
instance GHC.Classes.Eq Servant.Foreign.Internal.ArgType
instance Data.Data.Data Servant.Foreign.Internal.ArgType
instance GHC.Show.Show ftype => GHC.Show.Show (Servant.Foreign.Internal.Segment ftype)
instance GHC.Classes.Eq ftype => GHC.Classes.Eq (Servant.Foreign.Internal.Segment ftype)
instance Data.Data.Data ftype => Data.Data.Data (Servant.Foreign.Internal.Segment ftype)
instance GHC.Show.Show ftype => GHC.Show.Show (Servant.Foreign.Internal.SegmentType ftype)
instance GHC.Classes.Eq ftype => GHC.Classes.Eq (Servant.Foreign.Internal.SegmentType ftype)
instance Data.Data.Data ftype => Data.Data.Data (Servant.Foreign.Internal.SegmentType ftype)
instance GHC.Show.Show ftype => GHC.Show.Show (Servant.Foreign.Internal.Arg ftype)
instance GHC.Classes.Eq ftype => GHC.Classes.Eq (Servant.Foreign.Internal.Arg ftype)
instance Data.Data.Data ftype => Data.Data.Data (Servant.Foreign.Internal.Arg ftype)
instance GHC.Base.Monoid Servant.Foreign.Internal.PathSegment
instance GHC.Base.Semigroup Servant.Foreign.Internal.PathSegment
instance Data.String.IsString Servant.Foreign.Internal.PathSegment
instance GHC.Classes.Eq Servant.Foreign.Internal.PathSegment
instance GHC.Show.Show Servant.Foreign.Internal.PathSegment
instance Data.Data.Data Servant.Foreign.Internal.PathSegment
instance GHC.Base.Monoid Servant.Foreign.Internal.FunctionName
instance GHC.Base.Semigroup Servant.Foreign.Internal.FunctionName
instance GHC.Classes.Eq Servant.Foreign.Internal.FunctionName
instance GHC.Show.Show Servant.Foreign.Internal.FunctionName
instance Data.Data.Data Servant.Foreign.Internal.FunctionName

module Servant.Foreign.Inflections

-- | Simply concat each part of the FunctionName together.
--   
--   <pre>
--   [ "get", "documents", "by", "id" ] → "getdocumentsbyid"
--   </pre>
concatCase :: FunctionName -> Text

-- | Use the snake_case convention. Each part is separated by a single
--   underscore character.
--   
--   <pre>
--   [ "get", "documents", "by", "id" ] → "get_documents_by_id"
--   </pre>
snakeCase :: FunctionName -> Text

-- | Use the camelCase convention. The first part is lower case, every
--   other part starts with an upper case character.
--   
--   <pre>
--   [ "get", "documents", "by", "id" ] → "getDocumentsById"
--   </pre>
camelCase :: FunctionName -> Text
concatCaseL :: Getter FunctionName Text
snakeCaseL :: Getter FunctionName Text
camelCaseL :: Getter FunctionName Text


-- | Generalizes all the data needed to make code generation work with
--   arbitrary programming languages.
--   
--   See documentation of <a>HasForeignType</a> for a simple example.
--   <a>listFromAPI</a> returns a list of all your endpoints and their
--   foreign types, given a mapping from Haskell types to foreign types
--   (conventionally called <tt>ftypes</tt> below).
module Servant.Foreign

-- | Generate the necessary data for codegen as a list, each <a>Req</a>
--   describing one endpoint from your API type.
listFromAPI :: (HasForeign lang ftype api, GenerateList ftype (Foreign ftype api)) => Proxy lang -> Proxy ftype -> Proxy api -> [Req ftype]

-- | Full description of an endpoint in your API, generated by
--   <a>listFromAPI</a>. It should give you all the information needed to
--   generate foreign language bindings.
--   
--   Every field containing <tt>ftype</tt> will use the foreign type
--   mapping specified via <a>HasForeignType</a> (see its docstring on how
--   to set that up).
--   
--   See <a>https://docs.servant.dev/en/stable/tutorial/ApiType.html</a>
--   for accessible documentation of the possible content of an endpoint.
data Req ftype
Req :: Url ftype -> Method -> [HeaderArg ftype] -> Maybe ftype -> Maybe ftype -> FunctionName -> ReqBodyContentType -> Req ftype

-- | Full list of URL segments, including captures
[_reqUrl] :: Req ftype -> Url ftype

-- | <tt>"GET"</tt>/<tt>"POST"</tt>/<tt>"PUT"</tt>/…
[_reqMethod] :: Req ftype -> Method

-- | Headers required by this endpoint, with their type
[_reqHeaders] :: Req ftype -> [HeaderArg ftype]

-- | Foreign type of the expected request body (<a>ReqBody</a>), if any
[_reqBody] :: Req ftype -> Maybe ftype

-- | The foreign type of the response, if any
[_reqReturnType] :: Req ftype -> Maybe ftype

-- | The URL segments rendered in a way that they can be easily
--   concatenated into a canonical function name
[_reqFuncName] :: Req ftype -> FunctionName

-- | The content type the request body is transferred as.
--   
--   This is a severe limitation of <tt>servant-foreign</tt> currently, as
--   we only allow the content type to be <a>JSON</a> no user-defined
--   content types. (<a>ReqBodyMultipart</a> is not actually implemented.)
--   
--   Thus, any routes looking like this will work:
--   
--   <pre>
--   "foo" :&gt; Get '[JSON] Foo
--   </pre>
--   
--   while routes like
--   
--   <pre>
--   "foo" :&gt; Get '[MyFancyContentType] Foo
--   </pre>
--   
--   will fail with an error like
--   
--   <pre>
--   • JSON expected in list '[MyFancyContentType]
--   </pre>
[_reqBodyContentType] :: Req ftype -> ReqBodyContentType
defReq :: Req ftype

-- | <a>HasForeignType</a> maps Haskell types with types in the target
--   language of your backend. For example, let's say you're implementing a
--   backend to some language <b>X</b>, and you want a Text representation
--   of each input/output type mentioned in the API:
--   
--   <pre>
--   -- First you need to create a dummy type to parametrize your
--   -- instances.
--   data LangX
--   
--   -- Otherwise you define instances for the types you need
--   instance HasForeignType LangX Text Int where
--      typeFor _ _ _ = "intX"
--   
--   -- Or for example in case of lists
--   instance HasForeignType LangX Text a =&gt; HasForeignType LangX Text [a] where
--      typeFor lang type _ = "listX of " &lt;&gt; typeFor lang ftype (Proxy :: Proxy a)
--   </pre>
--   
--   Finally to generate list of information about all the endpoints for an
--   API you create a function of a form:
--   
--   <pre>
--   getEndpoints :: (HasForeign LangX Text api, GenerateList Text (Foreign Text api))
--                =&gt; Proxy api -&gt; [Req Text]
--   getEndpoints api = listFromAPI (Proxy :: Proxy LangX) (Proxy :: Proxy Text) api
--   </pre>
--   
--   <pre>
--   -- If language __X__ is dynamically typed then you can use
--   -- a predefined NoTypes parameter with the NoContent output type:
--   </pre>
--   
--   <pre>
--   getEndpoints :: (HasForeign NoTypes NoContent api, GenerateList Text (Foreign NoContent api))
--                =&gt; Proxy api -&gt; [Req NoContent]
--   getEndpoints api = listFromAPI (Proxy :: Proxy NoTypes) (Proxy :: Proxy NoContent) api
--   </pre>
class HasForeignType lang ftype a
typeFor :: HasForeignType lang ftype a => Proxy lang -> Proxy ftype -> Proxy a -> ftype

-- | Utility class used by <a>listFromAPI</a> which computes the data
--   needed to generate a function for each endpoint and hands it all back
--   in a list.
class GenerateList ftype reqs
generateList :: GenerateList ftype reqs => reqs -> [Req ftype]

-- | Implementation of the Servant framework types.
--   
--   Relevant instances: Everything containing <a>HasForeignType</a>.
class HasForeign lang ftype (api :: *) where {
    type Foreign ftype api :: *;
}
foreignFor :: HasForeign lang ftype api => Proxy lang -> Proxy ftype -> Proxy api -> Req ftype -> Foreign ftype api

-- | The language definition without any foreign types. It can be used for
--   dynamic languages which do not <i>do</i> type annotations.
data NoTypes

-- | Full endpoint url, with all captures and parameters
data Url ftype
Url :: Path ftype -> [QueryArg ftype] -> Maybe ftype -> Url ftype

-- | Url path, list of either static segments or captures
--   
--   <pre>
--   "foo/{id}/bar"
--   </pre>
[_path] :: Url ftype -> Path ftype

-- | List of query args
--   
--   <pre>
--   "?foo=bar&amp;a=b"
--   </pre>
[_queryStr] :: Url ftype -> [QueryArg ftype]

-- | Url fragment.
--   
--   Not sent to the HTTP server, so only useful for frontend matters (e.g.
--   inter-page linking).
--   
--   <pre>
--   #fragmentText
--   </pre>
[_frag] :: Url ftype -> Maybe ftype
type Path ftype = [Segment ftype]

-- | A part of the Url’s path.
newtype Segment ftype
Segment :: SegmentType ftype -> Segment ftype
[unSegment] :: Segment ftype -> SegmentType ftype
data SegmentType ftype

-- | Static path segment.
--   
--   <pre>
--   "foo/bar/baz"
--   </pre>
--   
--   contains the static segments <tt>"foo"</tt>, <tt>"bar"</tt> and
--   <tt>"baz"</tt>.
Static :: PathSegment -> SegmentType ftype

-- | A capture.
--   
--   <pre>
--   "user/{userid}/name"
--   </pre>
--   
--   would capture the arg <tt>userid</tt> with type <tt>ftype</tt>.
Cap :: Arg ftype -> SegmentType ftype

-- | Whether a segment is a <a>Cap</a>.
isCapture :: Segment ftype -> Bool

-- | Crashing Arg extraction from segment, TODO: remove
captureArg :: Segment ftype -> Arg ftype

-- | Url Query argument.
--   
--   Urls can contain query arguments, which is a list of key-value pairs.
--   In a typical url, query arguments look like this:
--   
--   <pre>
--   ?foo=bar&amp;alist[]=el1&amp;alist[]=el2&amp;aflag
--   </pre>
--   
--   Each pair can be
--   
--   <ul>
--   <li><tt>?foo=bar</tt>: a plain key-val pair, either optional or
--   required (<a>QueryParam</a>)</li>
--   <li><tt>?aflag</tt>: a flag (no value, implicitly Bool with default
--   <tt>false</tt> if it’s missing) (<a>QueryFlag</a>)</li>
--   <li><tt>?alist[]=el1&amp;alist[]=el2</tt>: list of values
--   (<a>QueryParams</a>)</li>
--   </ul>
--   
--   <tt>_queryArgType</tt> will be set accordingly.
--   
--   For the plain key-val pairs (<a>QueryParam</a>),
--   <tt>_queryArgName</tt>’s <tt>ftype</tt> will be wrapped in a
--   <tt>Maybe</tt> if the argument is optional.
data QueryArg ftype
QueryArg :: Arg ftype -> ArgType -> QueryArg ftype

-- | Name and foreign type of the argument. Will be wrapped in <a>Maybe</a>
--   if the query is optional and in a `[]` if the query is a list
[_queryArgName] :: QueryArg ftype -> Arg ftype

-- | one of normal/plain, list or flag
[_queryArgType] :: QueryArg ftype -> ArgType

-- | Type of a <a>QueryArg</a>.
data ArgType
Normal :: ArgType
Flag :: ArgType
List :: ArgType
data HeaderArg ftype

-- | The name of the header and the foreign type of its value.
HeaderArg :: Arg ftype -> HeaderArg ftype
[_headerArg] :: HeaderArg ftype -> Arg ftype

-- | Unused, will never be set.
--   
--   TODO: remove
ReplaceHeaderArg :: Arg ftype -> Text -> HeaderArg ftype
[_headerArg] :: HeaderArg ftype -> Arg ftype
[_headerPattern] :: HeaderArg ftype -> Text

-- | Maps a name to the foreign type that belongs to the annotated value.
--   
--   Used for header args, query args, and capture args.
data Arg ftype
Arg :: PathSegment -> ftype -> Arg ftype

-- | The name to be captured.
--   
--   Only for capture args it really denotes a path segment.
[_argName] :: Arg ftype -> PathSegment

-- | Foreign type the associated value will have
[_argType] :: Arg ftype -> ftype

-- | Canonical name of the endpoint, can be used to generate a function
--   name.
--   
--   You can use the functions in <a>Servant.Foreign.Inflections</a>, like
--   <a>camelCase</a> to transform to <a>ErrorMessage</a>.
newtype FunctionName
FunctionName :: [Text] -> FunctionName
[unFunctionName] :: FunctionName -> [Text]

-- | See documentation of <a>_reqBodyContentType</a>
data ReqBodyContentType
ReqBodyJSON :: ReqBodyContentType
ReqBodyMultipart :: ReqBodyContentType

-- | See documentation of <a>Arg</a>
newtype PathSegment
PathSegment :: Text -> PathSegment
[unPathSegment] :: PathSegment -> Text
argName :: forall ftype_a9Qc. Lens' (Arg ftype_a9Qc) PathSegment
argType :: forall ftype_a9Qc ftype_abPZ. Lens (Arg ftype_a9Qc) (Arg ftype_abPZ) ftype_a9Qc ftype_abPZ
argPath :: Getter (Arg ftype) Text
reqUrl :: forall ftype_acZb. Lens' (Req ftype_acZb) (Url ftype_acZb)
reqMethod :: forall ftype_acZb. Lens' (Req ftype_acZb) Method
reqHeaders :: forall ftype_acZb. Lens' (Req ftype_acZb) [HeaderArg ftype_acZb]
reqBody :: forall ftype_acZb. Lens' (Req ftype_acZb) (Maybe ftype_acZb)
reqBodyContentType :: forall ftype_acZb. Lens' (Req ftype_acZb) ReqBodyContentType
reqReturnType :: forall ftype_acZb. Lens' (Req ftype_acZb) (Maybe ftype_acZb)
reqFuncName :: forall ftype_acZb. Lens' (Req ftype_acZb) FunctionName
path :: forall ftype_acOC. Lens' (Url ftype_acOC) (Path ftype_acOC)
queryStr :: forall ftype_acOC. Lens' (Url ftype_acOC) [QueryArg ftype_acOC]
queryArgName :: forall ftype_acnI ftype_acD6. Lens (QueryArg ftype_acnI) (QueryArg ftype_acD6) (Arg ftype_acnI) (Arg ftype_acD6)
queryArgType :: forall ftype_acnI. Lens' (QueryArg ftype_acnI) ArgType
headerArg :: forall ftype_acDm ftype_acMF. Lens (HeaderArg ftype_acDm) (HeaderArg ftype_acMF) (Arg ftype_acDm) (Arg ftype_acMF)
_PathSegment :: Iso' PathSegment Text
_HeaderArg :: forall ftype_acDm. Prism' (HeaderArg ftype_acDm) (Arg ftype_acDm)
_ReplaceHeaderArg :: forall ftype_acDm. Prism' (HeaderArg ftype_acDm) (Arg ftype_acDm, Text)
_Static :: forall ftype_abQe. Prism' (SegmentType ftype_abQe) PathSegment
_Cap :: forall ftype_ac27 ftype_abQe. Prism (SegmentType ftype_ac27) (SegmentType ftype_abQe) (Arg ftype_ac27) (Arg ftype_abQe)
_Normal :: Prism' ArgType ()
_Flag :: Prism' ArgType ()
_List :: Prism' ArgType ()
