@@ -21,6 +21,7 @@ module Obelisk.Route
2121 , Encoder (..) --TODO: unsafe
2222 , checkEncoder
2323 , ValidEncoder (..) --TODO: unsafe
24+ , ValidEncoderFunc (..)
2425 , mapSome
2526 , pathComponentEncoder
2627 , enumEncoder
@@ -39,6 +40,8 @@ module Obelisk.Route
3940 , prismValidEncoder
4041 , rPrism
4142 , obeliskRouteEncoder
43+ , obeliskRouteComponentEncoder
44+ , checkObeliskRouteRestEncoder
4245 , pageNameValidEncoder
4346 , catchValidEncoder
4447 , ObeliskRoute (..)
@@ -50,6 +53,7 @@ module Obelisk.Route
5053 , IndexOnlyRoute (..)
5154 , indexOnlyRouteComponentEncoder
5255 , indexOnlyRouteRestEncoder
56+ , someSumEncoder
5357 ) where
5458
5559import Prelude hiding ((.), id)
@@ -63,7 +67,9 @@ import Control.Monad.Except
6367import Data.Dependent.Sum (DSum (..), ShowTag (..))
6468import Data.Dependent.Map (DMap)
6569import qualified Data.Dependent.Map as DMap
70+import Data.Either.Validation (Validation (..))
6671import Data.Foldable
72+import Data.Functor.Sum
6773import Data.GADT.Compare
6874import Data.GADT.Compare.TH
6975import Data.GADT.Show
@@ -78,7 +84,6 @@ import Data.Some (Some)
7884import qualified Data.Some as Some
7985import Data.Text (Text)
8086import qualified Data.Text as T
81−import Data.Either.Validation (Validation (..))
8287import Data.Universe
8388
8489-- Design goals:
@@ -232,7 +237,7 @@ shadowEncoder
232237 , Show c
233238 , check ~ parse --TODO: Get rid of this
234239 )
235− => Encoder check parse a c -- ^ Overlaps
240+ => Encoder check parse a c -- ^ Overlaps; should have a small number of possible routes
236241 -> Encoder check parse b c -- ^ Gets overlapped
237242 -> Encoder check parse (Either a b) c
238243shadowEncoder f g = Encoder $ do
@@ -471,13 +476,33 @@ obeliskRouteEncoder
471476 -> (forall a. appRoute a -> Encoder check parse a PageName)
472477 -> Encoder check parse (R (ObeliskRoute appRoute)) PageName
473478obeliskRouteEncoder appComponentEncoder appRouteEncoder = Encoder $ do
474− let componentEncoder = (resourceComponentEncoder `shadowEncoder` appComponentEncoder) . obeliskComponentEncoder
479+ let componentEncoder = obeliskRouteComponentEncoder appComponentEncoder
480+ restEncoder <- checkObeliskRouteRestEncoder appRouteEncoder
481+ checkEncoder $ pathComponentEncoder componentEncoder $ runValidEncoderFunc restEncoder
482+
483+checkObeliskRouteRestEncoder
484+ :: ( MonadError Text check
485+ , MonadError Text parse
486+ , Universe (Some appRoute)
487+ , GCompare appRoute
488+ )
489+ => (forall a. appRoute a -> Encoder check parse a PageName)
490+ -> check (ValidEncoderFunc parse (ObeliskRoute appRoute) PageName)
491+checkObeliskRouteRestEncoder appRouteEncoder = do
475492 appRouteValidEncoder <- checkSomeUniverseEncoder appRouteEncoder
476493 resourceRouteValidEncoder <- checkSomeUniverseEncoder resourceRouteEncoder
477− checkEncoder $ pathComponentEncoder componentEncoder $ \case
494+ return $ ValidEncoderFunc $ \case
478495 ObeliskRoute_App appRoute -> runValidEncoderFunc appRouteValidEncoder appRoute
479496 ObeliskRoute_Resource resRoute -> runValidEncoderFunc resourceRouteValidEncoder resRoute
480497
498+obeliskRouteComponentEncoder
499+ :: ( MonadError Text parse
500+ , GShow appRoute
501+ , check ~ parse
502+ )
503+ => Encoder check parse (Some appRoute) (Maybe Text) -> Encoder check parse (Some (ObeliskRoute appRoute)) (Maybe Text)
504+obeliskRouteComponentEncoder appComponentEncoder = (resourceComponentEncoder `shadowEncoder` appComponentEncoder) . obeliskComponentEncoder
505+
481506resourceComponentEncoder :: (MonadError Text check, MonadError Text parse) => Encoder check parse (Some ResourceRoute) (Maybe Text)
482507resourceComponentEncoder = enum1Encoder $ \case
483508 ResourceRoute_Static -> Just "static"
@@ -563,6 +588,16 @@ instance ShowTag IndexOnlyRoute Identity where
563588 showTaggedPrec = \case
564589 IndexOnlyRoute -> showsPrec
565590
591+someSumEncoder :: (Applicative check, Applicative parse) => Encoder check parse (Some (Sum a b)) (Either (Some a) (Some b))
592+someSumEncoder = Encoder $ pure $ ValidEncoder
593+ { _validEncoder_encode = \(Some.This t) -> case t of
594+ InL l -> Left $ Some.This l
595+ InR r -> Right $ Some.This r
596+ , _validEncoder_decode = pure . \case
597+ Left (Some.This l) -> Some.This (InL l)
598+ Right (Some.This r) -> Some.This (InR r)
599+ }
600+
566601makePrisms ''ObeliskRoute
567602--TODO: Prevent deriveGShow from creating this warning:
568603-- Defined but not used: ‘p’