@@ -12,6 +12,7 @@
1212{-# LANGUAGE PatternSynonyms #-}
1313{-# LANGUAGE RankNTypes #-}
1414{-# LANGUAGE ScopedTypeVariables #-}
15+{-# LANGUAGE StandaloneDeriving #-}
1516{-# LANGUAGE TemplateHaskell #-}
1617{-# LANGUAGE TypeApplications #-}
1718{-# LANGUAGE TypeFamilies #-}
@@ -66,6 +67,10 @@ module Obelisk.Route
6667 , obeliskRouteSegment
6768 , pageNameEncoder
6869 , handleEncoder
70+ , FullRoute (..)
71+ , _FullRoute_Frontend
72+ , _FullRoute_Backend
73+ , mkFullRouteEncoder
6974 , ObeliskRoute (..)
7075 , _ObeliskRoute_App
7176 , _ObeliskRoute_Resource
@@ -710,6 +715,45 @@ handleEncoder recover e = Encoder $ do
710715-- Actual obelisk route info
711716--------------------------------------------------------------------------------
712717
718+-- | The typical full route type comprising all of an Obelisk application's routes.
719+-- Parameterised by the top level GADTs that define backend and frontend routes, respectively.
720+data FullRoute :: (* -> *) -> (* -> *) -> * -> * where
721+ FullRoute_Backend :: br a -> FullRoute br fr a
722+ FullRoute_Frontend :: ObeliskRoute fr a -> FullRoute br fr a
723+
724+instance (GShow br, GShow fr) => GShow (FullRoute br fr) where
725+ gshowsPrec p = \case
726+ FullRoute_Backend x -> showParen (p > 10) (showString "FullRoute_Backend " . gshowsPrec 11 x)
727+ FullRoute_Frontend x -> showParen (p > 10) (showString "FullRoute_Frontend " . gshowsPrec 11 x)
728+
729+instance (GEq br, GEq fr) => GEq (FullRoute br fr) where
730+ geq (FullRoute_Backend x) (FullRoute_Backend y) = geq x y
731+ geq (FullRoute_Frontend x) (FullRoute_Frontend y) = geq x y
732+ geq _ _ = Nothing
733+
734+instance (GCompare br, GCompare fr) => GCompare (FullRoute br fr) where
735+ gcompare (FullRoute_Backend _) (FullRoute_Frontend _) = GLT
736+ gcompare (FullRoute_Frontend _) (FullRoute_Backend _) = GGT
737+ gcompare (FullRoute_Backend x) (FullRoute_Backend y) = gcompare x y
738+ gcompare (FullRoute_Frontend x) (FullRoute_Frontend y) = gcompare x y
739+
740+instance (UniverseSome br, UniverseSome fr) => UniverseSome (FullRoute br fr) where
741+ universeSome = [Some (FullRoute_Backend x) | Some x <- universeSome]
742+ ++ [Some (FullRoute_Frontend x) | Some x <- universeSome]
743+
744+-- | Build the typical top level application route encoder from a route for handling 404's,
745+-- and segment encoders for backend and frontend routes.
746+mkFullRouteEncoder
747+ :: (GCompare br, GCompare fr, GShow br, GShow fr, UniverseSome br, UniverseSome fr)
748+ => R (FullRoute br fr) -- ^ 404 handler
749+ -> (forall a. br a -> SegmentResult (Either Text) (Either Text) a) -- ^ How to encode a single backend route segment
750+ -> (forall a. fr a -> SegmentResult (Either Text) (Either Text) a) -- ^ How to encode a single frontend route segment
751+ -> Encoder (Either Text) Identity (R (FullRoute br fr)) PageName
752+mkFullRouteEncoder missing backendSegment frontendSegment = handleEncoder (const missing) $
753+ pathComponentEncoder $ \case
754+ FullRoute_Backend backendRoute -> backendSegment backendRoute
755+ FullRoute_Frontend obeliskRoute -> obeliskRouteSegment obeliskRoute frontendSegment
756+
713757-- | A type which can represent Obelisk-specific resource routes, in addition to application specific routes which serve your
714758-- frontend.
715759data ObeliskRoute :: (* -> *) -> * -> * where
@@ -839,7 +883,7 @@ concat <$> mapM deriveRouteComponent
839883 ]
840884
841885makePrisms ''ObeliskRoute
842−
886+makePrisms ''FullRoute
843887deriveGEq ''Void1
844888deriveGCompare ''Void1
845889