{-# LANGUAGE DeriveDataTypeable #-}

module Burrito.Internal.Type.Template (Template (..), render) where

import qualified Burrito.Internal.Render as Render
import qualified Burrito.Internal.Type.Token as Token
import qualified Data.Data as Data
import qualified Data.Text.Lazy.Builder as Builder

-- | Represents a URI template.
newtype Template = Template
  { Template -> [Token]
tokens :: [Token.Token]
  } deriving (Typeable Template
DataType
Constr
Typeable Template
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Template -> c Template)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Template)
-> (Template -> Constr)
-> (Template -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Template))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Template))
-> ((forall b. Data b => b -> b) -> Template -> Template)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Template -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Template -> r)
-> (forall u. (forall d. Data d => d -> u) -> Template -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Template -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Template -> m Template)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Template -> m Template)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Template -> m Template)
-> Data Template
Template -> DataType
Template -> Constr
(forall b. Data b => b -> b) -> Template -> Template
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Template -> c Template
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Template
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Template -> u
forall u. (forall d. Data d => d -> u) -> Template -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Template -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Template -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Template -> m Template
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Template -> m Template
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Template
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Template -> c Template
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Template)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Template)
$cTemplate :: Constr
$tTemplate :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Template -> m Template
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Template -> m Template
gmapMp :: (forall d. Data d => d -> m d) -> Template -> m Template
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Template -> m Template
gmapM :: (forall d. Data d => d -> m d) -> Template -> m Template
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Template -> m Template
gmapQi :: Int -> (forall d. Data d => d -> u) -> Template -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Template -> u
gmapQ :: (forall d. Data d => d -> u) -> Template -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Template -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Template -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Template -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Template -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Template -> r
gmapT :: (forall b. Data b => b -> b) -> Template -> Template
$cgmapT :: (forall b. Data b => b -> b) -> Template -> Template
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Template)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Template)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Template)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Template)
dataTypeOf :: Template -> DataType
$cdataTypeOf :: Template -> DataType
toConstr :: Template -> Constr
$ctoConstr :: Template -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Template
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Template
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Template -> c Template
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Template -> c Template
$cp1Data :: Typeable Template
Data.Data, Template -> Template -> Bool
(Template -> Template -> Bool)
-> (Template -> Template -> Bool) -> Eq Template
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Template -> Template -> Bool
$c/= :: Template -> Template -> Bool
== :: Template -> Template -> Bool
$c== :: Template -> Template -> Bool
Eq, Eq Template
Eq Template
-> (Template -> Template -> Ordering)
-> (Template -> Template -> Bool)
-> (Template -> Template -> Bool)
-> (Template -> Template -> Bool)
-> (Template -> Template -> Bool)
-> (Template -> Template -> Template)
-> (Template -> Template -> Template)
-> Ord Template
Template -> Template -> Bool
Template -> Template -> Ordering
Template -> Template -> Template
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Template -> Template -> Template
$cmin :: Template -> Template -> Template
max :: Template -> Template -> Template
$cmax :: Template -> Template -> Template
>= :: Template -> Template -> Bool
$c>= :: Template -> Template -> Bool
> :: Template -> Template -> Bool
$c> :: Template -> Template -> Bool
<= :: Template -> Template -> Bool
$c<= :: Template -> Template -> Bool
< :: Template -> Template -> Bool
$c< :: Template -> Template -> Bool
compare :: Template -> Template -> Ordering
$ccompare :: Template -> Template -> Ordering
$cp1Ord :: Eq Template
Ord)

instance Show Template where
  show :: Template -> String
show = Template -> String
render

-- | Renders a template back into a string. This is essentially the opposite of
-- @parse@. Usually you'll want to use @expand@ to actually substitute
-- variables in the template, but this can be useful for printing out the
-- template itself
--
-- >>> render <$> parse "valid-template"
-- Just "valid-template"
-- >>> render <$> parse "{var}"
-- Just "{var}"
render :: Template -> String
render :: Template -> String
render = Builder -> String
Render.builderToString (Builder -> String) -> (Template -> Builder) -> Template -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Template -> Builder
template

template :: Template -> Builder.Builder
template :: Template -> Builder
template = (Token -> Builder) -> [Token] -> Builder
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Token -> Builder
Render.token ([Token] -> Builder)
-> (Template -> [Token]) -> Template -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Template -> [Token]
tokens