Better overlapping support
This commit is contained in:
parent
3ee8e3c7f3
commit
fbf58cbc95
@ -9,7 +9,7 @@ import Data.Text (Text)
|
|||||||
import Web.ClientSession (Key)
|
import Web.ClientSession (Key)
|
||||||
import Yesod.Core (Route)
|
import Yesod.Core (Route)
|
||||||
import qualified Data.Vector as V
|
import qualified Data.Vector as V
|
||||||
import Data.Maybe (fromMaybe, mapMaybe, listToMaybe)
|
import Data.Maybe (fromMaybe, mapMaybe)
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import Data.List (sortBy)
|
import Data.List (sortBy)
|
||||||
import Data.Ord (comparing)
|
import Data.Ord (comparing)
|
||||||
@ -33,28 +33,33 @@ toDispatch rhs =
|
|||||||
|
|
||||||
bcToDispatch :: ByCount sub master res -> Dispatch sub master res
|
bcToDispatch :: ByCount sub master res -> Dispatch sub master res
|
||||||
bcToDispatch (ByCount vec rest) sub mkey ts master toMaster =
|
bcToDispatch (ByCount vec rest) sub mkey ts master toMaster =
|
||||||
case go ts rhs of
|
go (\x -> x sub mkey ts master toMaster) ts pm
|
||||||
Nothing -> Nothing
|
|
||||||
Just dispatch -> dispatch sub mkey ts master toMaster
|
|
||||||
where
|
where
|
||||||
len = length ts
|
--pm :: PieceMap sub master res
|
||||||
rhs = fromMaybe rest $ vec V.!? len
|
pm = fromMaybe rest $ vec V.!? length ts
|
||||||
|
|
||||||
go :: [Text]
|
go :: (Dispatch sub master res -> Maybe res)
|
||||||
|
-> [Text]
|
||||||
-> PieceMap sub master res
|
-> PieceMap sub master res
|
||||||
-> Maybe (Dispatch sub master res)
|
-> Maybe res
|
||||||
go _ (PieceMapEnd r) =
|
go runDispatch _ (PieceMapEnd r) =
|
||||||
listToMaybe $ map snd $ sortBy (comparing fst) r
|
firstJust runDispatch $ map snd $ sortBy (comparing fst) r
|
||||||
go (t:ts) (PieceMap dyn sta) = go ts $
|
go runDispatch (t:ts) (PieceMap dyn sta) = go runDispatch ts $
|
||||||
case Map.lookup t sta of
|
case Map.lookup t sta of
|
||||||
Nothing -> dyn
|
Nothing -> dyn
|
||||||
Just pm -> append dyn pm
|
Just pm -> append dyn pm
|
||||||
go [] _ = Nothing
|
go _ [] _ = Nothing
|
||||||
|
|
||||||
|
firstJust :: (a -> Maybe b) -> [a] -> Maybe b
|
||||||
|
firstJust _ [] = Nothing
|
||||||
|
firstJust f (a:as) = maybe (firstJust f as) Just $ f a
|
||||||
|
|
||||||
append :: PieceMap a b c -> PieceMap a b c -> PieceMap a b c
|
append :: PieceMap a b c -> PieceMap a b c -> PieceMap a b c
|
||||||
append (PieceMapEnd a) (PieceMapEnd b) = PieceMapEnd $ a ++ b
|
append (PieceMapEnd a) (PieceMapEnd b) = PieceMapEnd $ a ++ b
|
||||||
append (PieceMap a x) (PieceMap b y) =
|
append (PieceMap a x) (PieceMap b y) =
|
||||||
PieceMap (append a b) (Map.unionWith append x y)
|
PieceMap (append a b) (Map.unionWith append x y)
|
||||||
|
-- I'm sure there's some nice type-level trickery we could employ here somehow
|
||||||
|
-- to ensure this never happens.
|
||||||
append _ _ = error "Mismatched PieceMaps for append"
|
append _ _ = error "Mismatched PieceMaps for append"
|
||||||
|
|
||||||
data PieceMap sub master res = PieceMap
|
data PieceMap sub master res = PieceMap
|
||||||
@ -69,8 +74,7 @@ toPieceMap' :: Int
|
|||||||
-> [(Int, RouteHandler sub master res)]
|
-> [(Int, RouteHandler sub master res)]
|
||||||
-> PieceMap sub master res
|
-> PieceMap sub master res
|
||||||
toPieceMap' 0 rhs =
|
toPieceMap' 0 rhs =
|
||||||
PieceMapEnd $ take 1
|
PieceMapEnd $ map (second rhHandler)
|
||||||
$ map (second rhHandler)
|
|
||||||
$ sortBy (comparing fst) rhs
|
$ sortBy (comparing fst) rhs
|
||||||
toPieceMap' depth rhs = PieceMap
|
toPieceMap' depth rhs = PieceMap
|
||||||
{ pmDynamic = toPieceMap' depth' dynamics
|
{ pmDynamic = toPieceMap' depth' dynamics
|
||||||
@ -81,7 +85,9 @@ toPieceMap' depth rhs = PieceMap
|
|||||||
|
|
||||||
pairs = map toPair rhs
|
pairs = map toPair rhs
|
||||||
toPair (i, RouteHandler (p:ps) b c) = (p, (i, RouteHandler ps b c))
|
toPair (i, RouteHandler (p:ps) b c) = (p, (i, RouteHandler ps b c))
|
||||||
toPair _ = error "toPieceMap' received a route with empty pieces"
|
-- if we have no more pieces, that means this is a rhHasMulti, so fill in
|
||||||
|
-- with dynamic
|
||||||
|
toPair (i, RouteHandler [] b c) = (SinglePiece, (i, RouteHandler [] b c))
|
||||||
|
|
||||||
getDynamic (SinglePiece, rh) = Just rh
|
getDynamic (SinglePiece, rh) = Just rh
|
||||||
getDynamic _ = Nothing
|
getDynamic _ = Nothing
|
||||||
|
|||||||
@ -39,6 +39,13 @@ dynamic = toDispatch
|
|||||||
_ -> error $ "Called dynamic with: " ++ show ts
|
_ -> error $ "Called dynamic with: " ++ show ts
|
||||||
]
|
]
|
||||||
|
|
||||||
|
overlap :: Dispatch Dummy Dummy Int
|
||||||
|
overlap = toDispatch
|
||||||
|
[ RouteHandler [StaticPiece "foo"] False $ result $ const $ Just 20
|
||||||
|
, RouteHandler [StaticPiece "foo"] True $ result $ const $ Just 21
|
||||||
|
, RouteHandler [] True $ result $ const $ Just 22
|
||||||
|
]
|
||||||
|
|
||||||
test :: Dispatch Dummy Dummy Int -> [Text] -> Maybe Int
|
test :: Dispatch Dummy Dummy Int -> [Text] -> Maybe Int
|
||||||
test dispatch ts = dispatch Dummy Nothing ts Dummy id
|
test dispatch ts = dispatch Dummy Nothing ts Dummy id
|
||||||
|
|
||||||
@ -65,3 +72,8 @@ main = hspecX $ do
|
|||||||
it "fails correctly on five" $ test dynamic ["five"] @?= Nothing
|
it "fails correctly on five" $ test dynamic ["five"] @?= Nothing
|
||||||
it "fails correctly on too many" $ test dynamic ["foo", "baz"] @?= Nothing
|
it "fails correctly on too many" $ test dynamic ["foo", "baz"] @?= Nothing
|
||||||
it "fails correctly on too few" $ test dynamic [] @?= Nothing
|
it "fails correctly on too few" $ test dynamic [] @?= Nothing
|
||||||
|
describe "overlap" $ do
|
||||||
|
it "dispatches correctly to foo" $ test overlap ["foo"] @?= Just 20
|
||||||
|
it "dispatches correctly to foo/bar" $ test overlap ["foo", "bar"] @?= Just 21
|
||||||
|
it "dispatches correctly to bar" $ test overlap ["bar"] @?= Just 22
|
||||||
|
it "dispatches correctly to []" $ test overlap [] @?= Just 22
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user