4 , MultiParamTypeClasses
10 -- |An internal module for entity tags.
11 module Network.HTTP.Lucu.ETag
20 import Control.Applicative
22 import Data.Ascii (Ascii, AsciiBuilder)
23 import Data.Attoparsec.Char8
24 import Data.Convertible.Base
25 import Data.Convertible.Instances.Ascii ()
26 import Data.Convertible.Utils
28 import Data.Monoid.Unicode
29 import Language.Haskell.TH.Syntax
30 import Network.HTTP.Lucu.OrphanInstances ()
31 import Network.HTTP.Lucu.Parser.Http hiding (token)
32 import Network.HTTP.Lucu.Utils
33 import Prelude.Unicode
35 -- |An entity tag consists of a weakness flag and an opaque string.
37 -- |The weakness flag. Weak tags looks like @W\/\"blahblah\"@
38 -- and strong tags are like @\"blahblah\"@. See:
39 -- <http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.3>
41 -- |An opaque string. Only characters from 0x20 (sp) to 0x7e (~)
44 } deriving (Eq, Show, Data, Typeable)
46 instance Lift ETag where
49 etagIsWeak = $(lift etagIsWeak)
50 , etagToken = $(lift etagToken )
54 instance ConvertSuccess ETag Ascii where
55 {-# INLINE convertSuccess #-}
56 convertSuccess = convertSuccessVia ((⊥) ∷ AsciiBuilder)
58 instance ConvertSuccess ETag AsciiBuilder where
59 {-# INLINE convertSuccess #-}
60 convertSuccess (ETag {..})
61 = ( if etagIsWeak then
69 deriveAttempts [ ([t| ETag |], [t| Ascii |])
70 , ([t| ETag |], [t| AsciiBuilder |])
73 -- |This is equivalent to @'ETag' 'False'@. If you want to generate an
74 -- ETag from a file, try using
75 -- 'Network.HTTP.Lucu.StaticFile.generateETagFromFile'.
76 strongETag ∷ Ascii → ETag
77 {-# INLINE strongETag #-}
78 strongETag = ETag False
80 -- |This is equivalent to @'ETag' 'True'@.
81 weakETag ∷ Ascii → ETag
82 {-# INLINE weakETag #-}
85 -- |'Parser' for an 'ETag'.
87 {-# INLINEABLE eTag #-}
88 eTag = do isWeak ← option False (string "W/" *> return True)
90 return $ ETag isWeak str
92 -- |'Parser' for a list of 'ETag's.
93 eTagList ∷ Parser [ETag]
94 {-# INLINEABLE eTagList #-}
95 eTagList = do xs ← listOf eTag
97 fail "empty list of ETags"