@@ -0,0 +1,51 @@
1+{-# LANGUAGE EmptyCase #-}
2+{-# LANGUAGE FlexibleContexts #-}
3+{-# LANGUAGE GADTs #-}
4+{-# LANGUAGE LambdaCase #-}
5+{-# LANGUAGE RankNTypes #-}
6+{-# LANGUAGE TemplateHaskell #-}
7+{-# LANGUAGE KindSignatures #-}
8+{-# LANGUAGE EmptyCase #-}
9+{-# LANGUAGE MultiParamTypeClasses #-}
10+{-# LANGUAGE FlexibleInstances #-}
11+{-# LANGUAGE OverloadedStrings #-}
12+
13+module Common.Route where
14+
15+{- -- You will probably want these imports for composing Encoders.
16+import Prelude hiding (id, (.))
17+import Control.Category
18+-}
19+
20+import Data.Text (Text)
21+import Data.Functor.Identity
22+import Data.Functor.Sum
23+
24+import Obelisk.Route
25+import Obelisk.Route.TH
26+
27+data BackendRoute :: * -> * where
28+ -- | Used to handle unparseable routes.
29+ BackendRoute_Missing :: BackendRoute ()
30+ -- You can define any routes that will be handled specially by the backend here.
31+ -- i.e. These do not serve the frontend, but do something different, such as serving static files.
32+
33+data FrontendRoute :: * -> * where
34+ FrontendRoute_Main :: FrontendRoute ()
35+ -- This type is used to define frontend routes, i.e. ones for which the backend will serve the frontend.
36+
37+backendRouteEncoder
38+ :: Encoder (Either Text) Identity (R (Sum BackendRoute (ObeliskRoute FrontendRoute))) PageName
39+backendRouteEncoder = handleEncoder (const (InL BackendRoute_Missing :/ ())) $
40+ pathComponentEncoder $ \case
41+ InL backendRoute -> case backendRoute of
42+ BackendRoute_Missing -> PathSegment "missing" $ unitEncoder mempty
43+ InR obeliskRoute -> obeliskRouteSegment obeliskRoute $ \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
47+
48+concat <$> mapM deriveRouteComponent
49+ [ ''BackendRoute
50+ , ''FrontendRoute
51+ ]