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