@@ -18,32 +18,42 @@ import Control.Category
20import Data.Text (Text)
20import Data.Text (Text)
21+import qualified Data.Text as T
21import Data.Functor.Identity
23import Data.Functor.Identity
22−import Data.Functor.Sum
24+import Database.Id.Class (Id)
25+import Database.Id.Obelisk.Route (idPathSegmentEncoder)
24import Obelisk.Route
27import Obelisk.Route
25import Obelisk.Route.TH
28import Obelisk.Route.TH
27data BackendRoute :: * -> * where
32data BackendRoute :: * -> * where
28− -- | Used to handle unparseable routes.
29 BackendRoute_Missing :: BackendRoute ()
33 BackendRoute_Missing :: BackendRoute ()
30− -- You can define any routes that will be handled specially by the backend here.
34+ BackendRoute_Url_Id :: BackendRoute (Id Url)
31− -- i.e. These do not serve the frontend, but do something different, such as serving static files.
35+ -- TODO validate this or use a URL type
36+ BackendRoute_Shorten :: BackendRoute ()
33data FrontendRoute :: * -> * where
38data FrontendRoute :: * -> * where
34 FrontendRoute_Main :: FrontendRoute ()
39 FrontendRoute_Main :: FrontendRoute ()
35− -- This type is used to define frontend routes, i.e. ones for which the backend will serve the frontend.
40+
36−
41+checkedFullRouteEncoder
37−backendRouteEncoder
42+ :: Encoder Identity Identity (R (FullRoute BackendRoute FrontendRoute)) PageName
43+checkedFullRouteEncoder = checkEncoder fullRouteEncoder & \case
44+ Left err -> error $ T.unpack err
45+ Right encoder -> encoder
38− :: Encoder (Either Text) Identity (R (Sum BackendRoute (ObeliskRoute FrontendRoute))) PageName
48+ :: Encoder (Either Text) Identity (R (FullRoute BackendRoute FrontendRoute)) PageName
49+fullRouteEncoder = mkFullRouteEncoder
39−backendRouteEncoder = handleEncoder (const (InL BackendRoute_Missing :/ ())) $
50+ (FullRoute_Backend BackendRoute_Missing :/ ())
40− pathComponentEncoder $ \case
51+ (\case
41− InL backendRoute -> case backendRoute of
52+ BackendRoute_Shorten -> PathSegment "create" $ unitEncoder mempty
53+ BackendRoute_Url_Id -> PathSegment "s" idPathSegmentEncoder
42− BackendRoute_Missing -> PathSegment "missing" $ unitEncoder mempty
54+ BackendRoute_Missing -> PathSegment "missing" $ unitEncoder mempty)
43− InR obeliskRoute -> obeliskRouteSegment obeliskRoute $ \case
55+ (\case
44− -- The encoder given to PathEnd determines how to parse query parameters,
45− -- in this example, we have none, so we insist on it.
46− FrontendRoute_Main -> PathEnd $ unitEncoder mempty
56+ FrontendRoute_Main -> PathEnd $ unitEncoder mempty)
48concat <$> mapM deriveRouteComponent
58concat <$> mapM deriveRouteComponent
49 [ ''BackendRoute
59 [ ''BackendRoute