freckle-app 1.0.1.0 → 1.0.2.0
raw patch · 4 files changed
+74/−3 lines, 4 filesdep +template-haskell
Dependencies added: template-haskell
Files
- CHANGELOG.md +5/−1
- freckle-app.cabal +3/−1
- library/Freckle/App/Yesod/Routes.hs +64/−0
- package.yaml +2/−1
CHANGELOG.md view
@@ -1,6 +1,10 @@-## [_Unreleased_](https://github.com/freckle/freckle-app/compare/v1.0.1.0...main)+## [_Unreleased_](https://github.com/freckle/freckle-app/compare/v1.0.2.0...main) - None.++## [v1.0.2.0](https://github.com/freckle/freckle-app/compare/v1.0.1.0...v1.0.2.0)++- Add 'Freckle.App.Yesod.Route' to allow printing route names. ## [v1.0.1.0](https://github.com/freckle/freckle-app/compare/v1.0.0.4...v1.0.1.0)
freckle-app.cabal view
@@ -1,6 +1,6 @@ cabal-version: 1.12 name: freckle-app-version: 1.0.1.0+version: 1.0.2.0 license: MIT license-file: LICENSE maintainer: Freckle Education@@ -45,6 +45,7 @@ Freckle.App.Version Freckle.App.Wai Freckle.App.Yesod+ Freckle.App.Yesod.Routes Network.HTTP.Link.Compat hs-source-dirs: library@@ -101,6 +102,7 @@ resource-pool >=0.2.3.2, retry >=0.8.1.2, rio >=0.1.20.0,+ template-haskell >=2.16.0.0, text >=1.2.4.1, time >=1.9.3, transformers >=0.5.6.2,
+ library/Freckle/App/Yesod/Routes.hs view
@@ -0,0 +1,64 @@+module Freckle.App.Yesod.Routes+ ( mkRouteNameCaseExp+ ) where++import Prelude++import Data.Foldable (fold)+import qualified Language.Haskell.TH as TH+import Yesod.Routes.TH.Types++-- | Lambdacase expression to print route names+--+-- It has the following type:+--+-- > _ :: Route a -> String+--+-- It produces code like:+--+-- > \case+-- > RoutePiece a -> case a of+-- > RouteResource{} -> "ResourceName"+--+mkRouteNameCaseExp :: [ResourceTree String] -> TH.Q TH.Exp+mkRouteNameCaseExp tree = TH.LamCaseE . fold <$> traverse mkMatches tree++-- | Make match expressions for a big case over routes+--+-- > RoutePiece a -> case a of+-- > ...+--+mkMatches :: ResourceTree String -> TH.Q [TH.Match]+mkMatches (ResourceLeaf resource) = pure [mkLeafMatch resource]+mkMatches (ResourceParent name _checkOverlap params children) = do+ caseVar <- TH.newName "a"+ let+ -- by convention the final param in a route is the next route constructor+ paramVars =+ fmap (const TH.WildP) (filter isDynamic params) <> [TH.VarP caseVar]+ matches <- fold <$> traverse mkMatches children+ pure+ [ TH.Match+ (TH.ConP constName paramVars)+ (TH.NormalB $ TH.CaseE (TH.VarE caseVar) matches)+ []+ ]+ where constName = TH.mkName name++isDynamic :: Piece a -> Bool+isDynamic = \case+ Static{} -> False+ Dynamic{} -> True++-- | Leaf match expressions for a resource+--+-- > Name{} -> "ResourceName"+--+mkLeafMatch :: Resource String -> TH.Match+mkLeafMatch resource = TH.Match+ (TH.RecP constName [])+ (TH.NormalB $ TH.LitE $ TH.StringL name)+ []+ where+ constName = TH.mkName name+ name = resourceName resource
package.yaml view
@@ -1,6 +1,6 @@ --- name: freckle-app-version: 1.0.1.0+version: 1.0.2.0 maintainer: Freckle Education category: Utils github: freckle/freckle-app@@ -90,6 +90,7 @@ - resource-pool - retry - rio+ - template-haskell - text - time - transformers