3 , MultiParamTypeClasses
6 module Network.HTTP.Lucu.Dispatcher.Node
10 import Data.Collections
11 import qualified Data.Map as M
13 import Data.Monoid.Unicode
14 import Network.HTTP.Lucu.Resource.Internal
15 import Network.HTTP.Lucu.Utils
16 import Prelude hiding (filter, null)
17 import Prelude.Unicode
22 | NonGreedy !Resource !SubTree
26 = M.Map PathSegment ResourceNode
28 instance Show ResourceNode where
29 show (Greedy _ ) = "Greedy _"
30 show (NonGreedy _ m) = "NonGreedy _ " ⊕ show m
31 show (Branch m) = "Branch " ⊕ show m
33 instance Monoid ResourceNode where
36 {-# INLINEABLE mappend #-}
37 mappend (Greedy r ) _ = Greedy r
38 mappend (NonGreedy r m) (Greedy _ ) = NonGreedy r m
39 mappend (NonGreedy r m) (NonGreedy _ n) = NonGreedy r (m ⊕ n)
40 mappend (NonGreedy r m) (Branch n) = NonGreedy r (m ⊕ n)
41 mappend (Branch _) (Greedy r ) = Greedy r
42 mappend (Branch m) (NonGreedy r n) = NonGreedy r (m ⊕ n)
43 mappend (Branch m) (Branch n) = Branch (m ⊕ n)
45 instance Unfoldable ResourceNode (PathSegments, ResourceNode) where
46 {-# INLINEABLE insert #-}
47 insert (p, n) = insertNodeAt (canonPath p) n
51 canonPath ∷ (Collection c f, Foldable f e) ⇒ c → c
52 {-# INLINEABLE canonPath #-}
53 canonPath = filter ((¬) ∘ null)
55 insertNodeAt ∷ PathSegments → ResourceNode → ResourceNode → ResourceNode
56 {-# INLINEABLE insertNodeAt #-}
61 | null xs → Branch (singleton (x, a)) ⊕ b
62 | otherwise → insertNodeAt xs a (∅) ⊕ b
64 instance Foldable ResourceNode (PathSegments, ResourceNode) where
67 go p (Greedy r ) = f (p, Greedy r)
68 go p (NonGreedy r m) = f (p, NonGreedy r (∅)) ⊕ go' p m
69 go p (Branch m) = go' p m
71 go' p = foldMap $ \(s, n) → go (p `snoc` s) n
73 null (Greedy _ ) = False
74 null (NonGreedy _ _) = False
75 null (Branch m) = null m