{-# LANGUAGE DeriveDataTypeable , FlexibleInstances , MultiParamTypeClasses , OverloadedStrings , RecordWildCards , TemplateHaskell , UnicodeSyntax #-} -- |An internal module for entity tags. module Network.HTTP.Lucu.ETag ( ETag(..) , strongETag , weakETag , eTag , eTagList ) where import Control.Applicative import Control.Monad import Data.Ascii (Ascii, AsciiBuilder) import Data.Attoparsec.Char8 import Data.Convertible.Base import Data.Convertible.Instances.Ascii () import Data.Convertible.Utils import Data.Data import Data.Monoid.Unicode import Language.Haskell.TH.Syntax import Network.HTTP.Lucu.OrphanInstances () import Network.HTTP.Lucu.Parser.Http hiding (token) import Network.HTTP.Lucu.Utils import Prelude.Unicode -- |An entity tag consists of a weakness flag and an opaque string. data ETag = ETag { -- |The weakness flag. Weak tags looks like @W\/\"blahblah\"@ -- and strong tags are like @\"blahblah\"@. See: -- etagIsWeak ∷ !Bool -- |An opaque string. Only characters from 0x20 (sp) to 0x7e (~) -- are allowed. , etagToken ∷ !Ascii } deriving (Eq, Show, Data, Typeable) instance Lift ETag where lift (ETag {..}) = [| ETag { etagIsWeak = $(lift etagIsWeak) , etagToken = $(lift etagToken ) } |] instance ConvertSuccess ETag Ascii where {-# INLINE convertSuccess #-} convertSuccess = convertSuccessVia ((⊥) ∷ AsciiBuilder) instance ConvertSuccess ETag AsciiBuilder where {-# INLINE convertSuccess #-} convertSuccess (ETag {..}) = ( if etagIsWeak then cs ("W/" ∷ Ascii) else (∅) ) ⊕ quoteStr etagToken deriveAttempts [ ([t| ETag |], [t| Ascii |]) , ([t| ETag |], [t| AsciiBuilder |]) ] -- |This is equivalent to @'ETag' 'False'@. If you want to generate an -- ETag from a file, try using -- 'Network.HTTP.Lucu.StaticFile.generateETagFromFile'. strongETag ∷ Ascii → ETag {-# INLINE strongETag #-} strongETag = ETag False -- |This is equivalent to @'ETag' 'True'@. weakETag ∷ Ascii → ETag {-# INLINE weakETag #-} weakETag = ETag True -- |'Parser' for an 'ETag'. eTag ∷ Parser ETag {-# INLINEABLE eTag #-} eTag = do isWeak ← option False (string "W/" *> return True) str ← quotedStr return $ ETag isWeak str -- |'Parser' for a list of 'ETag's. eTagList ∷ Parser [ETag] {-# INLINEABLE eTagList #-} eTagList = do xs ← listOf eTag when (null xs) $ fail "empty list of ETags" return xs