1 module Webc.Encoder where
3 import Control.Monad (Monad (..))
4 import Control.Monad.Trans.Reader qualified as MT
5 import Data.Either (Either (..))
6 import Data.Foldable (foldMap)
7 import Data.Function (id, ($))
9 -- import Data.List qualified as List
10 import Data.Maybe (Maybe (..))
11 import Data.Monoid (Endo (..), appEndo)
12 import Data.Semigroup (Semigroup (..))
13 import Network.URI.Slug
14 import Symantic.Classes (Iso (..), IsoFunctor ((<%>)), Optionable (..), ProductFunctor ((<.>)), SumFunctor ((<+>)))
18 -- * The 'Encoder' interpreter
20 -- | Encode a given route to its URL.
21 newtype Encoder a = Encoder
22 { unEncoder :: MT.Reader a (Endo [Slug])
25 encode :: Encoder a -> a -> [Slug]
26 encode (Encoder enc) a = appEndo (MT.runReader enc a) []
28 instance IsoFunctor Encoder where
29 Iso{..} <%> Encoder x = Encoder (MT.withReader b2a x)
30 instance ProductFunctor Encoder where
31 Encoder x <.> Encoder y = Encoder $
32 MT.ReaderT $ \(a, b) ->
36 instance SumFunctor Encoder where
37 Encoder x <+> Encoder y = Encoder $
39 Left a -> return $ MT.runReader x a
40 Right b -> return $ MT.runReader y b
41 instance Repeatable Encoder where
44 return $ Endo (foldMap (encode x) as <>)
46 instance Optionable Encoder where
47 optional (Encoder x) = Encoder $
49 Nothing -> return $ Endo id
50 Just a -> return $ MT.runReader x a
51 instance Slugable Encoder where
52 literalSlug s = Encoder $ return $ Endo (s :)
53 chooseSlug _s = Encoder $ MT.ReaderT $ \s -> return $ Endo (s :)
55 -- chooseSlugs _s = Encoder $ MT.ReaderT $ \s -> return $ Endo (List.reverse s <>)
56 instance Capturable Encoder where
57 captureSlug _n = Encoder $ MT.ReaderT $ \s -> return $ Endo (s :)
58 instance Endable Encoder where
59 end = Encoder $ return $ Endo id
61 --chooseSlug _cs = Encoder $ MT.ReaderT $ \s -> return $ Endo (s :)
62 -- instance Fileable Encoder where
63 -- type FileableConstraint Encoder = Typeable
64 -- static = Encoder $ MT.ReaderT $ \_a ->
65 -- return $ Endo (\x -> x)