{-# OPTIONS_HADDOCK prune #-}

-- |Manipulation of entity tags.
module Network.HTTP.Lucu.ETag
    ( ETag(..)
    , strongETag
    , weakETag
    , eTagP
    , eTagListP
    )
    where

import           Control.Monad
import           Network.HTTP.Lucu.Parser
import           Network.HTTP.Lucu.Parser.Http hiding (token)
import           Network.HTTP.Lucu.Utils

-- |An entity tag is made of a weakness flag and a opaque string.
data ETag = ETag {
      -- |The weakness flag. Weak tags looks like W\/\"blahblah\" and
      -- strong tags are like \"blahblah\".
      etagIsWeak :: !Bool
      -- |An opaque string. Only characters from 0x20 (sp) to 0x7e (~)
      -- are allowed.
    , etagToken  :: !String
    } deriving (Eq)

instance Show ETag where
    show (ETag isWeak token) = (if isWeak then
                                    "W/"
                                else
                                    "")
                               ++
                               quoteStr token

-- |This is equivalent to @'ETag' 'Prelude.False'@. If you want to
-- generate an ETag from a file, try using
-- 'Network.HTTP.Lucu.StaticFile.generateETagFromFile'.
strongETag :: String -> ETag
strongETag = ETag False

-- |This is equivalent to @'ETag' 'Prelude.True'@.
weakETag :: String -> ETag
weakETag = ETag True


eTagP :: Parser ETag
eTagP = do isWeak <- option False (string "W/" >> return True)
           str    <- quotedStr
           return $ ETag isWeak str


eTagListP :: Parser [ETag]
eTagListP = allowEOF
            $! do xs <- listOf eTagP
                  when (null xs)
                           $ fail ""
                  return xs