{-# LANGUAGE OverloadedStrings, UnicodeSyntax, Safe, CPP #-}

module Network.HTTP.Link.Writer (
  writeLink
, writeLinkHeader
) where

import           Data.Text hiding (map)
#if !MIN_VERSION_base(4,8,0)
import           Data.Monoid (mconcat)
#endif
import           Network.URI
import           Network.HTTP.Link.Types

writeParamKey  LinkParam  Text
writeParamKey :: LinkParam -> Text
writeParamKey Rel = "rel"
writeParamKey Anchor = "anchor"
writeParamKey Rev = "rev"
writeParamKey Hreflang = "hreflang"
writeParamKey Media = "media"
writeParamKey Title = "title"
writeParamKey Title' = "title*"
writeParamKey ContentType = "type"
writeParamKey (Other t :: Text
t) = Text
t

writeParam  (LinkParam, Text)  Text
writeParam :: (LinkParam, Text) -> Text
writeParam (t :: LinkParam
t, v :: Text
v) = [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat ["; ", LinkParam -> Text
writeParamKey LinkParam
t, "=\"", Text -> Text
escPar Text
v, "\""]
  where escPar :: Text -> Text
escPar = String -> Text
pack (String -> Text) -> (Text -> String) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> String
escapeURIString (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= '"') (String -> String) -> (Text -> String) -> Text -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack
        -- maybe URI escaping is not what we should do here? eh, whatever

writeLink  Link  Text
writeLink :: Link -> Text
writeLink l :: Link
l = [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ ["<", String -> Text
pack (String -> Text) -> (URI -> String) -> URI -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. URI -> String
forall a. Show a => a -> String
show (URI -> Text) -> URI -> Text
forall a b. (a -> b) -> a -> b
$ Link -> URI
href Link
l, ">"] [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ ((LinkParam, Text) -> Text) -> [(LinkParam, Text)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (LinkParam, Text) -> Text
writeParam (Link -> [(LinkParam, Text)]
linkParams Link
l)

writeLinkHeader  [Link]  Text
writeLinkHeader :: [Link] -> Text
writeLinkHeader = Text -> [Text] -> Text
intercalate ", " ([Text] -> Text) -> ([Link] -> [Text]) -> [Link] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Link -> Text) -> [Link] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Link -> Text
writeLink