@@ -57,6 +57,7 @@ module Obelisk.Route
5757 -- * Collating Routes
5858 , SegmentResult (.. )
5959 , pathComponentEncoder
60+ , pathComponentEncoderIgnoringQuery
6061
6162 , FullRoute (.. )
6263 , _FullRoute_Frontend
@@ -80,6 +81,7 @@ module Obelisk.Route
8081 , enum1Encoder
8182 , checkEnum1EncoderFunc
8283 , unitEncoder
84+ , unitEncoderLenient
8385 , pathOnlyEncoder
8486 , addPathSegmentEncoder
8587 , pathParamEncoder
@@ -119,6 +121,7 @@ module Obelisk.Route
119121 , queryParametersTextEncoder
120122 , integralEncoder
121123 , pathSegmentEncoder
124+ , pathOnlyEncoderIgnoringQuery
122125 , queryOnlyEncoder
123126 , Decoder (.. )
124127 , dmapEncoder
@@ -577,32 +580,56 @@ checkEnum1EncoderFunc f = do
577580
578581-- | This type is used by pathComponentEncoder to allow the user to indicate how to treat
579582-- various cases when encoding a dependent sum of type `(R p)`.
580- data SegmentResult check parse a =
581- PathEnd (Encoder check parse a ( Map Text ( Maybe Text )) )
583+ data SegmentResult check parse a b =
584+ PathEnd (Encoder check parse a b )
582585 -- ^ Indicate that the path is finished, with an Encoder that translates the
583586 -- corresponding value into query parameters
584- | PathSegment Text (Encoder check parse a PageName )
587+ | PathSegment Text (Encoder check parse a ([ Text ], b ) )
585588 -- ^ Indicate that the key should be represented by an additional path segment with
586589 -- the given 'Text', and give an Encoder for translating the corresponding value into
587590 -- the remainder of the route.
588591
592+ pathComponentEncoderIgnoringQuery
593+ :: ( Universe (Some p )
594+ , GShow p
595+ , GCompare p
596+ , MonadError Text check
597+ , MonadError Text parse
598+ )
599+ => (forall a . p a -> SegmentResult check parse a () )
600+ -> Encoder check parse (R p ) PageName
601+ pathComponentEncoderIgnoringQuery = pathComponentEncoder' $ \ case
602+ PathEnd e -> first (unitEncoder [] ) . coidl . unitEncoderLenient mempty . e
603+ PathSegment _ e -> pathOnlyEncoderIgnoringQuery . idr . e
604+
605+ pathComponentEncoder
606+ :: ( Universe (Some p )
607+ , GShow p
608+ , GCompare p
609+ , MonadError Text check
610+ , MonadError Text parse
611+ )
612+ => (forall a . p a -> SegmentResult check parse a (Map Text (Maybe Text )))
613+ -> Encoder check parse (R p ) PageName
614+ pathComponentEncoder = pathComponentEncoder' $ \ case
615+ PathEnd e -> first (unitEncoder [] ) . coidl . e
616+ PathSegment _ e -> e
617+
589618-- | Encode a dependent sum of type `(R p)` into a PageName (i.e. the path and query part of a URL) by using the
590619-- supplied function to decide how to encode the constructors of p using the SegmentResult type. It is important
591620-- that the number of values of type `(Some p)` be relatively small in order for checking to complete quickly.
592- pathComponentEncoder
593- :: forall check parse p .
594- ( Universe (Some p )
621+ pathComponentEncoder'
622+ :: ( Universe (Some p )
595623 , GShow p
596624 , GCompare p
597625 , MonadError Text check
598- , MonadError Text parse )
599- => (forall a . p a -> SegmentResult check parse a )
626+ , MonadError Text parse
627+ )
628+ => (forall a . SegmentResult check parse a b -> Encoder check parse a PageName )
629+ -> (forall a . p a -> SegmentResult check parse a b )
600630 -> Encoder check parse (R p ) PageName
601- pathComponentEncoder f = Encoder $ do
602- let extractEncoder = \ case
603- PathEnd e -> first (unitEncoder [] ) . coidl . e
604- PathSegment _ e -> e
605- extractPathSegment = \ case
631+ pathComponentEncoder' extractEncoder f = Encoder $ do
632+ let extractPathSegment = \ case
606633 PathEnd _ -> Nothing
607634 PathSegment t _ -> Just t
608635 EncoderFunc f' <- checkEnum1EncoderFunc (extractEncoder . f)
@@ -737,6 +764,12 @@ unitEncoder expected = unsafeMkEncoder $ EncoderImpl
737764 , _encoderImpl_encode = \ _ -> expected
738765 }
739766
767+ unitEncoderLenient :: (Applicative check , Applicative parse ) => r -> Encoder check parse () r
768+ unitEncoderLenient expected = unsafeMkEncoder $ EncoderImpl
769+ { _encoderImpl_decode = \ _ -> pure ()
770+ , _encoderImpl_encode = \ _ -> expected
771+ }
772+
740773singlePathSegmentEncoder :: (Applicative check , MonadError Text parse ) => Encoder check parse Text PageName
741774singlePathSegmentEncoder = pathOnlyEncoder . singletonListEncoder
742775
@@ -976,8 +1009,8 @@ instance (UniverseSome br, UniverseSome fr) => UniverseSome (FullRoute br fr) w
9761009mkFullRouteEncoder
9771010 :: (GCompare br , GCompare fr , GShow br , GShow fr , UniverseSome br , UniverseSome fr )
9781011 => R (FullRoute br fr ) -- ^ 404 handler
979- -> (forall a . br a -> SegmentResult (Either Text ) (Either Text ) a ) -- ^ How to encode a single backend route segment
980- -> (forall a . fr a -> SegmentResult (Either Text ) (Either Text ) a ) -- ^ How to encode a single frontend route segment
1012+ -> (forall a . br a -> SegmentResult (Either Text ) (Either Text ) a ( Map Text ( Maybe Text )) ) -- ^ How to encode a single backend route segment
1013+ -> (forall a . fr a -> SegmentResult (Either Text ) (Either Text ) a ( Map Text ( Maybe Text )) ) -- ^ How to encode a single frontend route segment
9811014 -> Encoder (Either Text ) Identity (R (FullRoute br fr )) PageName
9821015mkFullRouteEncoder missing backendSegment frontendSegment = handleEncoder (const missing) $
9831016 pathComponentEncoder $ \ case
@@ -1027,7 +1060,7 @@ obeliskRouteEncoder :: forall check parse appRoute.
10271060 , MonadError Text check
10281061 , check ~ parse -- TODO: Get rid of this
10291062 )
1030- => (forall a . appRoute a -> SegmentResult check parse a )
1063+ => (forall a . appRoute a -> SegmentResult check parse a ( Map Text ( Maybe Text )) )
10311064 -> Encoder check parse (R (ObeliskRoute appRoute )) PageName
10321065obeliskRouteEncoder appRouteSegment = pathComponentEncoder $ \ r ->
10331066 obeliskRouteSegment r appRouteSegment
@@ -1038,15 +1071,15 @@ obeliskRouteEncoder appRouteSegment = pathComponentEncoder $ \r ->
10381071obeliskRouteSegment :: forall check parse appRoute a .
10391072 (MonadError Text check , MonadError Text parse )
10401073 => ObeliskRoute appRoute a
1041- -> (forall b . appRoute b -> SegmentResult check parse b )
1042- -> SegmentResult check parse a
1074+ -> (forall b . appRoute b -> SegmentResult check parse b ( Map Text ( Maybe Text )) )
1075+ -> SegmentResult check parse a ( Map Text ( Maybe Text ))
10431076obeliskRouteSegment r appRouteSegment = case r of
10441077 ObeliskRoute_App appRoute -> appRouteSegment appRoute
10451078 ObeliskRoute_Resource resourceRoute -> resourceRouteSegment resourceRoute
10461079
10471080-- | A function which gives a sane default for how to encode Obelisk resource routes. It's given in this form, because it will
10481081-- be combined with other such segment encoders before 'pathComponentEncoder' turns it into a proper 'Encoder'.
1049- resourceRouteSegment :: (MonadError Text check , MonadError Text parse ) => ResourceRoute a -> SegmentResult check parse a
1082+ resourceRouteSegment :: (MonadError Text check , MonadError Text parse ) => ResourceRoute a -> SegmentResult check parse a ( Map Text ( Maybe Text ))
10501083resourceRouteSegment = \ case
10511084 ResourceRoute_Static -> PathSegment " static" pathOnlyEncoderIgnoringQuery
10521085 ResourceRoute_Ghcjs -> PathSegment " ghcjs" pathOnlyEncoder
@@ -1074,7 +1107,7 @@ instance GShow appRoute => GShow (ObeliskRoute appRoute) where
10741107data IndexOnlyRoute :: * -> * where
10751108 IndexOnlyRoute :: IndexOnlyRoute ()
10761109
1077- indexOnlyRouteSegment :: (Applicative check , MonadError Text parse ) => IndexOnlyRoute a -> SegmentResult check parse a
1110+ indexOnlyRouteSegment :: (Applicative check , MonadError Text parse ) => IndexOnlyRoute a -> SegmentResult check parse a ( Map Text ( Maybe Text ))
10781111indexOnlyRouteSegment = \ case
10791112 IndexOnlyRoute -> PathEnd $ unitEncoder mempty
10801113
0 commit comments