{-# LANGUAGE
    KindSignatures
  , GADTs
  , RankNTypes
  , TypeOperators
  , DataKinds
  #-}

module Web.Routes.Nested.Types.UrlChunks where

import Data.Attoparsec.Text
import qualified Data.Text as T


-- | Constrained to AttoParsec & T.Text
data EitherUrlChunk (x :: Maybe *) where
  (:=) :: T.Text             -> EitherUrlChunk 'Nothing
  (:~) :: (T.Text, Parser r) -> EitherUrlChunk ('Just r)

-- | Container when defining route paths
data UrlChunks (xs :: [Maybe *]) where
  Cons :: EitherUrlChunk mx -> UrlChunks xs -> UrlChunks (mx ': xs) -- unpacks left-to-right
  Root  :: UrlChunks '[]

-- `foldChunks :: (forall mx. EitherUrlChunk mx -> acc -> acc) -> acc -> UrlChunks xs -> acc
-- `foldChunks f i Root = i
-- `foldChunks f i (Cons u us) = foldChunks f (f u i) us
-- `
-- `appendChunks :: UrlChunks xs -> UrlChunks ys -> UrlChunks (xs :++ ys)
-- `appendChunks Root ys = ys
-- `appendChunks (Cons x xs) ys = Cons x $ appendChunks xs ys
-- `
-- `lastChunk :: UrlChunks xs -> EitherUrlChunk (Last xs)
-- `lastChunk (Cons u Root) = u
-- `lastChunk (Cons u us)   = lastChunk us
-- `
-- `initChunks :: UrlChunks xs -> UrlChunks (Init xs)
-- `initChunks (Cons u Root) = Root
-- `initChunks (Cons u us)   = Cons u $ initChunks us

(</>) = Cons

infixr 8 </>

(#) = Root