{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableInstances #-}

module Ema.Route.Generic.Example where

import Data.Generics.Sum.Any (AsAny (_As))
import Data.SOP (I (..), NP (..))
import Ema
import Ema.Asset qualified as Asset
import Ema.Route.Generic
import Ema.Route.Generic.TH
import Generics.SOP qualified as SOP
import Generics.SOP.TH qualified as SOP
import Optics.Core ((%))
import Optics.Prism (prism')

-- ----------
-- Examples
-- ----------

type M = (Int, Int, String)

data R = R_Index | R_Foo | R_Bar NumRoute | R_Bar2 NumRoute
  deriving stock (Int -> R -> ShowS
[R] -> ShowS
R -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [R] -> ShowS
$cshowList :: [R] -> ShowS
show :: R -> String
$cshow :: R -> String
showsPrec :: Int -> R -> ShowS
$cshowsPrec :: Int -> R -> ShowS
Show, R -> R -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: R -> R -> Bool
$c/= :: R -> R -> Bool
== :: R -> R -> Bool
$c== :: R -> R -> Bool
Eq, forall x. Rep R x -> R
forall x. R -> Rep R x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep R x -> R
$cfrom :: forall x. R -> Rep R x
Generic)
  deriving anyclass (All @[Type] (SListI @Type) (Code R)
Rep R -> R
R -> Rep R
forall a.
All @[Type] (SListI @Type) (Code a)
-> (a -> Rep a) -> (Rep a -> a) -> Generic a
to :: Rep R -> R
$cto :: Rep R -> R
from :: R -> Rep R
$cfrom :: R -> Rep R
SOP.Generic, Generic R
forall a.
Generic a
-> (forall (proxy :: Type -> Type).
    proxy a -> DatatypeInfo (Code a))
-> HasDatatypeInfo a
forall (proxy :: Type -> Type). proxy R -> DatatypeInfo (Code R)
datatypeInfo :: forall (proxy :: Type -> Type). proxy R -> DatatypeInfo (Code R)
$cdatatypeInfo :: forall (proxy :: Type -> Type). proxy R -> DatatypeInfo (Code R)
SOP.HasDatatypeInfo)
  deriving (forall {k} (r :: k). HasSubRoutes @k r
HasSubRoutes, RouteModel R -> [R]
RouteModel R -> Prism_ String R
forall r.
(RouteModel r -> Prism_ String r)
-> (RouteModel r -> [r]) -> IsRoute r
routeUniverse :: RouteModel R -> [R]
$crouteUniverse :: RouteModel R -> [R]
routePrism :: RouteModel R -> Prism_ String R
$croutePrism :: RouteModel R -> Prism_ String R
IsRoute) via (GenericRoute R '[WithModel M])

-- We must derive this manually due to ambiguity in field types (Int)
instance HasSubModels R where
  subModels :: RouteModel R -> NP @Type I (MultiModel (SubRoutes @Type R))
subModels (Int
a, Int
b, String
_) =
    forall a. a -> I a
I () forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
a x -> NP @k a xs -> NP @k a ((':) @k x xs)
:* forall a. a -> I a
I () forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
a x -> NP @k a xs -> NP @k a ((':) @k x xs)
:* forall a. a -> I a
I Int
a forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
a x -> NP @k a xs -> NP @k a ((':) @k x xs)
:* forall a. a -> I a
I Int
b forall {k} (a :: k -> Type) (x :: k) (xs :: [k]).
a x -> NP @k a xs -> NP @k a ((':) @k x xs)
:* forall {k} (a :: k -> Type). NP @k a ('[] @k)
Nil

data NumRoute = NumRoute
  deriving stock (Int -> NumRoute -> ShowS
[NumRoute] -> ShowS
NumRoute -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NumRoute] -> ShowS
$cshowList :: [NumRoute] -> ShowS
show :: NumRoute -> String
$cshow :: NumRoute -> String
showsPrec :: Int -> NumRoute -> ShowS
$cshowsPrec :: Int -> NumRoute -> ShowS
Show, NumRoute -> NumRoute -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NumRoute -> NumRoute -> Bool
$c/= :: NumRoute -> NumRoute -> Bool
== :: NumRoute -> NumRoute -> Bool
$c== :: NumRoute -> NumRoute -> Bool
Eq, forall x. Rep NumRoute x -> NumRoute
forall x. NumRoute -> Rep NumRoute x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep NumRoute x -> NumRoute
$cfrom :: forall x. NumRoute -> Rep NumRoute x
Generic)

instance IsRoute NumRoute where
  type RouteModel NumRoute = Int
  routePrism :: RouteModel NumRoute -> Prism_ String NumRoute
routePrism RouteModel NumRoute
n =
    let fp :: String
fp = forall b a. (Show a, IsString b) => a -> b
show RouteModel NumRoute
n forall a. Semigroup a => a -> a -> a
<> String
".html"
     in forall s a. Prism' s a -> Prism_ s a
toPrism_ forall a b. (a -> b) -> a -> b
$
          forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism' (forall a b. a -> b -> a
const String
fp) forall a b. (a -> b) -> a -> b
$ \String
s -> do
            forall (f :: Type -> Type). Alternative f => Bool -> f ()
guard forall a b. (a -> b) -> a -> b
$ String
s forall a. Eq a => a -> a -> Bool
== String
fp
            forall (f :: Type -> Type) a. Applicative f => a -> f a
pure NumRoute
NumRoute
  routeUniverse :: RouteModel NumRoute -> [NumRoute]
routeUniverse RouteModel NumRoute
_ = [NumRoute
NumRoute]

instance EmaSite R where
  siteInput :: forall (m :: Type -> Type).
(MonadIO m, MonadUnliftIO m, MonadLoggerIO m) =>
Some @Type Action -> SiteArg R -> m (Dynamic m (RouteModel R))
siteInput Some @Type Action
_ () = forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Int
42, Int
21, String
"inner")
  siteOutput :: forall (m :: Type -> Type).
(MonadIO m, MonadLoggerIO m) =>
Prism' String R -> RouteModel R -> R -> m (SiteOutput R)
siteOutput Prism' String R
_ RouteModel R
m R
r = forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Format -> a -> Asset a
Asset.AssetGenerated Format
Asset.Html forall a b. (a -> b) -> a -> b
$ forall b a. (Show a, IsString b) => a -> b
show R
r forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show RouteModel R
m

-- --warnings -c "cabal repl ema -f with-examples" -T Ema.Route.Generic.main  --setup ":set args gen /tmp"
main :: IO ()
main :: IO ()
main = forall r. (Show r, Eq r, EmaStaticSite r) => SiteArg r -> IO ()
Ema.runSite_ @R ()

-- ---
-- Let's try defining a top-level route using `R` to see how EmaSite instances compose.
-- --

type TM = (M, String)

data TR = TR_Index | TR_Inner R
  deriving stock (Int -> TR -> ShowS
[TR] -> ShowS
TR -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TR] -> ShowS
$cshowList :: [TR] -> ShowS
show :: TR -> String
$cshow :: TR -> String
showsPrec :: Int -> TR -> ShowS
$cshowsPrec :: Int -> TR -> ShowS
Show, TR -> TR -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TR -> TR -> Bool
$c/= :: TR -> TR -> Bool
== :: TR -> TR -> Bool
$c== :: TR -> TR -> Bool
Eq, forall x. Rep TR x -> TR
forall x. TR -> Rep TR x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TR x -> TR
$cfrom :: forall x. TR -> Rep TR x
Generic)
  deriving anyclass (All @[Type] (SListI @Type) (Code TR)
Rep TR -> TR
TR -> Rep TR
forall a.
All @[Type] (SListI @Type) (Code a)
-> (a -> Rep a) -> (Rep a -> a) -> Generic a
to :: Rep TR -> TR
$cto :: Rep TR -> TR
from :: TR -> Rep TR
$cfrom :: TR -> Rep TR
SOP.Generic, Generic TR
forall a.
Generic a
-> (forall (proxy :: Type -> Type).
    proxy a -> DatatypeInfo (Code a))
-> HasDatatypeInfo a
forall (proxy :: Type -> Type). proxy TR -> DatatypeInfo (Code TR)
datatypeInfo :: forall (proxy :: Type -> Type). proxy TR -> DatatypeInfo (Code TR)
$cdatatypeInfo :: forall (proxy :: Type -> Type). proxy TR -> DatatypeInfo (Code TR)
SOP.HasDatatypeInfo)
  deriving (forall {k} (r :: k). HasSubRoutes @k r
HasSubRoutes, HasSubRoutes @Type TR
RouteModel TR -> NP @Type I (MultiModel (SubRoutes @Type TR))
forall r.
HasSubRoutes @Type r
-> (RouteModel r -> NP @Type I (MultiModel (SubRoutes @Type r)))
-> HasSubModels r
subModels :: RouteModel TR -> NP @Type I (MultiModel (SubRoutes @Type TR))
$csubModels :: RouteModel TR -> NP @Type I (MultiModel (SubRoutes @Type TR))
HasSubModels, RouteModel TR -> [TR]
RouteModel TR -> Prism_ String TR
forall r.
(RouteModel r -> Prism_ String r)
-> (RouteModel r -> [r]) -> IsRoute r
routeUniverse :: RouteModel TR -> [TR]
$crouteUniverse :: RouteModel TR -> [TR]
routePrism :: RouteModel TR -> Prism_ String TR
$croutePrism :: RouteModel TR -> Prism_ String TR
IsRoute) via (GenericRoute TR '[WithModel TM])

instance EmaSite TR where
  siteInput :: forall (m :: Type -> Type).
(MonadIO m, MonadUnliftIO m, MonadLoggerIO m) =>
Some @Type Action -> SiteArg TR -> m (Dynamic m (RouteModel TR))
siteInput Some @Type Action
x () = do
    Dynamic m M
m1 <- forall r (m :: Type -> Type).
(EmaSite r, MonadIO m, MonadUnliftIO m, MonadLoggerIO m) =>
Some @Type Action -> SiteArg r -> m (Dynamic m (RouteModel r))
siteInput @R Some @Type Action
x ()
    forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (,String
"TOP") Dynamic m M
m1
  siteOutput :: forall (m :: Type -> Type).
(MonadIO m, MonadLoggerIO m) =>
Prism' String TR -> RouteModel TR -> TR -> m (SiteOutput TR)
siteOutput Prism' String TR
rp RouteModel TR
m = \case
    r :: TR
r@TR
TR_Index ->
      forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Format -> a -> Asset a
Asset.AssetGenerated Format
Asset.Html forall a b. (a -> b) -> a -> b
$ forall b a. (Show a, IsString b) => a -> b
show TR
r forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show RouteModel TR
m
    TR_Inner R
r ->
      -- Might as well provide a `innerSiteOutput (_As @TR_Inner)`?
      forall r (m :: Type -> Type).
(EmaSite r, MonadIO m, MonadLoggerIO m) =>
Prism' String r -> RouteModel r -> r -> m (SiteOutput r)
siteOutput @R (Prism' String TR
rp forall k l m (is :: [Type]) (js :: [Type]) (ks :: [Type]) s t u v a
       b.
(JoinKinds k l m, AppendIndices is js ks) =>
Optic k is s t u v -> Optic l js u v a b -> Optic m ks s t a b
% forall {k} (sel :: k) a s. AsAny @k sel a s => Prism s s a a
_As @"TR_Inner") (TM -> M
trInnerModel RouteModel TR
m) R
r
    where
      trInnerModel :: TM -> M
trInnerModel TM
model =
        let I () :* I x
M
m' :* NP @Type I xs
Nil = forall r.
HasSubModels r =>
RouteModel r -> NP @Type I (MultiModel (SubRoutes @Type r))
subModels @TR TM
model
         in M
m'

mainTop :: IO ()
mainTop :: IO ()
mainTop = forall r. (Show r, Eq r, EmaStaticSite r) => SiteArg r -> IO ()
Ema.runSite_ @TR ()

-- ---
-- Ensure that the constant model case (simple one) still works
-- --

type M2 = (Int, String)

data R2 = R2_Index | R2_Foo | R2_Bar BarRoute | R2_Bar2 BarRoute
  deriving stock (Int -> R2 -> ShowS
[R2] -> ShowS
R2 -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [R2] -> ShowS
$cshowList :: [R2] -> ShowS
show :: R2 -> String
$cshow :: R2 -> String
showsPrec :: Int -> R2 -> ShowS
$cshowsPrec :: Int -> R2 -> ShowS
Show, R2 -> R2 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: R2 -> R2 -> Bool
$c/= :: R2 -> R2 -> Bool
== :: R2 -> R2 -> Bool
$c== :: R2 -> R2 -> Bool
Eq, forall x. Rep R2 x -> R2
forall x. R2 -> Rep R2 x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep R2 x -> R2
$cfrom :: forall x. R2 -> Rep R2 x
Generic)
  deriving anyclass (All @[Type] (SListI @Type) (Code R2)
Rep R2 -> R2
R2 -> Rep R2
forall a.
All @[Type] (SListI @Type) (Code a)
-> (a -> Rep a) -> (Rep a -> a) -> Generic a
to :: Rep R2 -> R2
$cto :: Rep R2 -> R2
from :: R2 -> Rep R2
$cfrom :: R2 -> Rep R2
SOP.Generic, Generic R2
forall a.
Generic a
-> (forall (proxy :: Type -> Type).
    proxy a -> DatatypeInfo (Code a))
-> HasDatatypeInfo a
forall (proxy :: Type -> Type). proxy R2 -> DatatypeInfo (Code R2)
datatypeInfo :: forall (proxy :: Type -> Type). proxy R2 -> DatatypeInfo (Code R2)
$cdatatypeInfo :: forall (proxy :: Type -> Type). proxy R2 -> DatatypeInfo (Code R2)
SOP.HasDatatypeInfo)
  deriving (forall {k} (r :: k). HasSubRoutes @k r
HasSubRoutes, HasSubRoutes @Type R2
RouteModel R2 -> NP @Type I (MultiModel (SubRoutes @Type R2))
forall r.
HasSubRoutes @Type r
-> (RouteModel r -> NP @Type I (MultiModel (SubRoutes @Type r)))
-> HasSubModels r
subModels :: RouteModel R2 -> NP @Type I (MultiModel (SubRoutes @Type R2))
$csubModels :: RouteModel R2 -> NP @Type I (MultiModel (SubRoutes @Type R2))
HasSubModels, RouteModel R2 -> [R2]
RouteModel R2 -> Prism_ String R2
forall r.
(RouteModel r -> Prism_ String r)
-> (RouteModel r -> [r]) -> IsRoute r
routeUniverse :: RouteModel R2 -> [R2]
$crouteUniverse :: RouteModel R2 -> [R2]
routePrism :: RouteModel R2 -> Prism_ String R2
$croutePrism :: RouteModel R2 -> Prism_ String R2
IsRoute) via (GenericRoute R2 '[WithModel M2])

data BarRoute = BarRoute
  deriving stock (Int -> BarRoute -> ShowS
[BarRoute] -> ShowS
BarRoute -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BarRoute] -> ShowS
$cshowList :: [BarRoute] -> ShowS
show :: BarRoute -> String
$cshow :: BarRoute -> String
showsPrec :: Int -> BarRoute -> ShowS
$cshowsPrec :: Int -> BarRoute -> ShowS
Show, BarRoute -> BarRoute -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BarRoute -> BarRoute -> Bool
$c/= :: BarRoute -> BarRoute -> Bool
== :: BarRoute -> BarRoute -> Bool
$c== :: BarRoute -> BarRoute -> Bool
Eq, forall x. Rep BarRoute x -> BarRoute
forall x. BarRoute -> Rep BarRoute x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep BarRoute x -> BarRoute
$cfrom :: forall x. BarRoute -> Rep BarRoute x
Generic)
  deriving anyclass (All @[Type] (SListI @Type) (Code BarRoute)
Rep BarRoute -> BarRoute
BarRoute -> Rep BarRoute
forall a.
All @[Type] (SListI @Type) (Code a)
-> (a -> Rep a) -> (Rep a -> a) -> Generic a
to :: Rep BarRoute -> BarRoute
$cto :: Rep BarRoute -> BarRoute
from :: BarRoute -> Rep BarRoute
$cfrom :: BarRoute -> Rep BarRoute
SOP.Generic, Generic BarRoute
forall a.
Generic a
-> (forall (proxy :: Type -> Type).
    proxy a -> DatatypeInfo (Code a))
-> HasDatatypeInfo a
forall (proxy :: Type -> Type).
proxy BarRoute -> DatatypeInfo (Code BarRoute)
datatypeInfo :: forall (proxy :: Type -> Type).
proxy BarRoute -> DatatypeInfo (Code BarRoute)
$cdatatypeInfo :: forall (proxy :: Type -> Type).
proxy BarRoute -> DatatypeInfo (Code BarRoute)
SOP.HasDatatypeInfo)
  deriving (forall {k} (r :: k). HasSubRoutes @k r
HasSubRoutes, HasSubRoutes @Type BarRoute
RouteModel BarRoute
-> NP @Type I (MultiModel (SubRoutes @Type BarRoute))
forall r.
HasSubRoutes @Type r
-> (RouteModel r -> NP @Type I (MultiModel (SubRoutes @Type r)))
-> HasSubModels r
subModels :: RouteModel BarRoute
-> NP @Type I (MultiModel (SubRoutes @Type BarRoute))
$csubModels :: RouteModel BarRoute
-> NP @Type I (MultiModel (SubRoutes @Type BarRoute))
HasSubModels, RouteModel BarRoute -> [BarRoute]
RouteModel BarRoute -> Prism_ String BarRoute
forall r.
(RouteModel r -> Prism_ String r)
-> (RouteModel r -> [r]) -> IsRoute r
routeUniverse :: RouteModel BarRoute -> [BarRoute]
$crouteUniverse :: RouteModel BarRoute -> [BarRoute]
routePrism :: RouteModel BarRoute -> Prism_ String BarRoute
$croutePrism :: RouteModel BarRoute -> Prism_ String BarRoute
IsRoute) via (GenericRoute BarRoute '[WithModel M2])

instance EmaSite R2 where
  siteInput :: forall (m :: Type -> Type).
(MonadIO m, MonadUnliftIO m, MonadLoggerIO m) =>
Some @Type Action -> SiteArg R2 -> m (Dynamic m (RouteModel R2))
siteInput Some @Type Action
_ () = forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Int
21, String
"inner")
  siteOutput :: forall (m :: Type -> Type).
(MonadIO m, MonadLoggerIO m) =>
Prism' String R2 -> RouteModel R2 -> R2 -> m (SiteOutput R2)
siteOutput Prism' String R2
_ RouteModel R2
m R2
r = forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Format -> a -> Asset a
Asset.AssetGenerated Format
Asset.Html forall a b. (a -> b) -> a -> b
$ forall b a. (Show a, IsString b) => a -> b
show R2
r forall a. Semigroup a => a -> a -> a
<> forall b a. (Show a, IsString b) => a -> b
show RouteModel R2
m

mainConst :: IO ()
mainConst :: IO ()
mainConst = forall r. (Show r, Eq r, EmaStaticSite r) => SiteArg r -> IO ()
Ema.runSite_ @R2 ()

-- ---
-- Ensure deriveIsRoute works with (partial) subroutes
-- --

data M3
  = M3
  deriving stock (M3 -> M3 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: M3 -> M3 -> Bool
$c/= :: M3 -> M3 -> Bool
== :: M3 -> M3 -> Bool
$c== :: M3 -> M3 -> Bool
Eq, Int -> M3 -> ShowS
[M3] -> ShowS
M3 -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [M3] -> ShowS
$cshowList :: [M3] -> ShowS
show :: M3 -> String
$cshow :: M3 -> String
showsPrec :: Int -> M3 -> ShowS
$cshowsPrec :: Int -> M3 -> ShowS
Show, forall x. Rep M3 x -> M3
forall x. M3 -> Rep M3 x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep M3 x -> M3
$cfrom :: forall x. M3 -> Rep M3 x
Generic)

data R3
  = R3_Sub R3_SubR
  | R3_Index

data R3_SubR
  = R3_SubR
  deriving stock (Int -> R3_SubR -> ShowS
[R3_SubR] -> ShowS
R3_SubR -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [R3_SubR] -> ShowS
$cshowList :: [R3_SubR] -> ShowS
show :: R3_SubR -> String
$cshow :: R3_SubR -> String
showsPrec :: Int -> R3_SubR -> ShowS
$cshowsPrec :: Int -> R3_SubR -> ShowS
Show, R3_SubR -> R3_SubR -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: R3_SubR -> R3_SubR -> Bool
$c/= :: R3_SubR -> R3_SubR -> Bool
== :: R3_SubR -> R3_SubR -> Bool
$c== :: R3_SubR -> R3_SubR -> Bool
Eq, Eq R3_SubR
R3_SubR -> R3_SubR -> Bool
R3_SubR -> R3_SubR -> Ordering
R3_SubR -> R3_SubR -> R3_SubR
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: R3_SubR -> R3_SubR -> R3_SubR
$cmin :: R3_SubR -> R3_SubR -> R3_SubR
max :: R3_SubR -> R3_SubR -> R3_SubR
$cmax :: R3_SubR -> R3_SubR -> R3_SubR
>= :: R3_SubR -> R3_SubR -> Bool
$c>= :: R3_SubR -> R3_SubR -> Bool
> :: R3_SubR -> R3_SubR -> Bool
$c> :: R3_SubR -> R3_SubR -> Bool
<= :: R3_SubR -> R3_SubR -> Bool
$c<= :: R3_SubR -> R3_SubR -> Bool
< :: R3_SubR -> R3_SubR -> Bool
$c< :: R3_SubR -> R3_SubR -> Bool
compare :: R3_SubR -> R3_SubR -> Ordering
$ccompare :: R3_SubR -> R3_SubR -> Ordering
Ord, forall x. Rep R3_SubR x -> R3_SubR
forall x. R3_SubR -> Rep R3_SubR x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep R3_SubR x -> R3_SubR
$cfrom :: forall x. R3_SubR -> Rep R3_SubR x
Generic)
  deriving anyclass (All @[Type] (SListI @Type) (Code R3_SubR)
Rep R3_SubR -> R3_SubR
R3_SubR -> Rep R3_SubR
forall a.
All @[Type] (SListI @Type) (Code a)
-> (a -> Rep a) -> (Rep a -> a) -> Generic a
to :: Rep R3_SubR -> R3_SubR
$cto :: Rep R3_SubR -> R3_SubR
from :: R3_SubR -> Rep R3_SubR
$cfrom :: R3_SubR -> Rep R3_SubR
SOP.Generic, Generic R3_SubR
forall a.
Generic a
-> (forall (proxy :: Type -> Type).
    proxy a -> DatatypeInfo (Code a))
-> HasDatatypeInfo a
forall (proxy :: Type -> Type).
proxy R3_SubR -> DatatypeInfo (Code R3_SubR)
datatypeInfo :: forall (proxy :: Type -> Type).
proxy R3_SubR -> DatatypeInfo (Code R3_SubR)
$cdatatypeInfo :: forall (proxy :: Type -> Type).
proxy R3_SubR -> DatatypeInfo (Code R3_SubR)
SOP.HasDatatypeInfo)
  deriving
    (forall {k} (r :: k). HasSubRoutes @k r
HasSubRoutes, HasSubRoutes @Type R3_SubR
RouteModel R3_SubR
-> NP @Type I (MultiModel (SubRoutes @Type R3_SubR))
forall r.
HasSubRoutes @Type r
-> (RouteModel r -> NP @Type I (MultiModel (SubRoutes @Type r)))
-> HasSubModels r
subModels :: RouteModel R3_SubR
-> NP @Type I (MultiModel (SubRoutes @Type R3_SubR))
$csubModels :: RouteModel R3_SubR
-> NP @Type I (MultiModel (SubRoutes @Type R3_SubR))
HasSubModels, RouteModel R3_SubR -> [R3_SubR]
RouteModel R3_SubR -> Prism_ String R3_SubR
forall r.
(RouteModel r -> Prism_ String r)
-> (RouteModel r -> [r]) -> IsRoute r
routeUniverse :: RouteModel R3_SubR -> [R3_SubR]
$crouteUniverse :: RouteModel R3_SubR -> [R3_SubR]
routePrism :: RouteModel R3_SubR -> Prism_ String R3_SubR
$croutePrism :: RouteModel R3_SubR -> Prism_ String R3_SubR
IsRoute)
    via ( GenericRoute
            R3_SubR
            '[ WithSubRoutes
                '[ FileRoute "example.html"
                 ]
             ]
        )

SOP.deriveGeneric ''R3
deriveIsRoute
  ''R3
  [t|
    [ WithModel M3
    , WithSubRoutes
        [ R3_SubR
        , ()
        ]
    ]
    |]

-- ---
-- Ensure deriveIsRoute works in a no-subroute case
-- --

data M4
  = M4
  deriving stock (M4 -> M4 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: M4 -> M4 -> Bool
$c/= :: M4 -> M4 -> Bool
== :: M4 -> M4 -> Bool
$c== :: M4 -> M4 -> Bool
Eq, Int -> M4 -> ShowS
[M4] -> ShowS
M4 -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [M4] -> ShowS
$cshowList :: [M4] -> ShowS
show :: M4 -> String
$cshow :: M4 -> String
showsPrec :: Int -> M4 -> ShowS
$cshowsPrec :: Int -> M4 -> ShowS
Show, forall x. Rep M4 x -> M4
forall x. M4 -> Rep M4 x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep M4 x -> M4
$cfrom :: forall x. M4 -> Rep M4 x
Generic)

data R4
  = R4_Index
  | R3_About

SOP.deriveGeneric ''R4
deriveIsRoute ''R4 [t|'[WithModel M4]|]