@@ -21,6 +21,8 @@
2121module Obelisk.Route
2222 ( R
2323 , pattern (:/)
24+ , (:.)
25+ , pattern (:.)
2426 , hoistR
2527 , PageName
2628 , PathQuery
@@ -43,6 +45,9 @@ module Obelisk.Route
4345 , checkEnum1EncoderFunc
4446 , unitEncoder
4547 , pathOnlyEncoder
48+ , addPathSegmentEncoder
49+ , pathParamEncoder
50+ , pathLiteralEncoder
4651 , singletonListEncoder
4752 , unpackTextEncoder
4853 , prefixTextEncoder
@@ -200,6 +205,48 @@ mapSome f (Some a) = Some $ f a
200205hoistR :: (forall x. f x -> g x) -> R f -> R g
201206hoistR f (x :=> Identity y) = f x :/ y
202207
208+--------------------------------------------------------------------------------
209+-- Dealing with pairs (i.e. non-dependently-typed subroutes/paths)
210+--------------------------------------------------------------------------------
211+
212+infixr 5 :.
213+type (:.) = (,)
214+
215+{-# COMPLETE (:.) #-}
216+pattern (:.) :: a -> b -> a :. b
217+pattern a :. b = (a, b)
218+
219+addPathSegmentEncoder
220+ :: ( Applicative check
221+ , MonadError Text parse
222+ )
223+ => Encoder check parse (Text, PageName) PageName
224+addPathSegmentEncoder = unsafeMkEncoder $ EncoderImpl
225+ { _encoderImpl_encode = \(ph, (pt, q)) -> (ph : pt, q)
226+ , _encoderImpl_decode = \(p, q) -> case p of
227+ [] -> throwError "Expected a path segment"
228+ ph : pt -> pure (ph, (pt, q))
229+ }
230+
231+pathParamEncoder
232+ :: forall check parse item rest.
233+ ( Applicative check
234+ , MonadError Text parse
235+ )
236+ => Encoder check parse item Text
237+ -> Encoder check parse rest PageName
238+ -> Encoder check parse (item :. rest) PageName
239+pathParamEncoder itemUnchecked restUnchecked = addPathSegmentEncoder . bimap itemUnchecked restUnchecked
240+
241+pathLiteralEncoder
242+ :: ( Applicative check
243+ , MonadError Text parse
244+ )
245+ => Text
246+ -> Encoder check parse a PageName
247+ -> Encoder check parse a PageName
248+pathLiteralEncoder t e = addPathSegmentEncoder . bimap (unitEncoder t) e . coidl
249+
203250--------------------------------------------------------------------------------
204251-- Encoder fundamentals
205252--------------------------------------------------------------------------------