haskell-servant / haskell-servant/servant

How to capture a path segment optionally? (was: Any reason why CaptureHint is not exported?)

Open
#1,795 8 comments 0 reactions 0 assignees View on GitHub
Dominant language
Haskell
Stars
2k
Forks
427
Avg merge
2d 23h
Merged PRs (30d)
5

Description

I am knee-deep into finding a solution for [How to optionally capture a path segment in Haskell servant?](https://stackoverflow.com/questions/79240975/how-to-optionally-capture-a-path-segment-in-haskell-servant) and I think I have hit upon something that could work (given below) BUT it won't compile without access to `Servant.Server.Internal.Router.CaptureHint`. Any reason why it has not been exported? Without access to that type, is there any other way to use `addCapture`?

```haskell
data HostWithLocale = HostWithLocale

instance (HasServer api context) => HasServer (HostWithLocale :> api) context where
type ServerT (HostWithLocale :> api) m = (Hostname, Maybe LanguageCode) -> ServerT api m

hoistServerWithContext _ pc nt s = hoistServerWithContext (Proxy :: Proxy api) pc nt . s

route _ context server =
CaptureRouter [hint] $ route (Proxy :: Proxy api) context subserver
where
hint = CaptureHint "language" (typeRep (Proxy :: Proxy (Hostname, Maybe LanguageCode)))
subserver = addCapture server $ \pathSegment -> withRequest $ \req ->
case DL.lookup (fromString "Host") (requestHeaders req) of
Nothing ->
delayedFail err406
Just hname ->
if Prelude.not (isWhiteListedDomain hname)
then delayedFail err406
else if pathSegment `DL.elem` knownLanguageCodes
then pure $ (toS hname, Just $ LanguageCode pathSegment)
else pure $ (toS hname, Nothing)

isWhiteListedDomain :: C8.ByteString -> Bool
isWhiteListedDomain = undefined

knownLanguageCodes :: [Text]
knownLanguageCodes = undefined
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.