5 -- |Manipulation of entity tags.
6 module Network.HTTP.Lucu.ETag
17 import Control.Applicative
19 import Data.Ascii (Ascii)
20 import qualified Data.Ascii as A
21 import Data.Attoparsec.Char8
22 import Data.Monoid.Unicode
23 import Network.HTTP.Lucu.Parser.Http hiding (token)
24 import Network.HTTP.Lucu.Utils
25 import Prelude.Unicode
27 -- |An entity tag is made of a weakness flag and a opaque string.
29 -- |The weakness flag. Weak tags looks like W\/\"blahblah\" and
30 -- strong tags are like \"blahblah\".
32 -- |An opaque string. Only characters from 0x20 (sp) to 0x7e (~)
37 -- |Convert an 'ETag' to 'Ascii'.
38 printETag ∷ ETag → Ascii
40 = A.fromAsciiBuilder $
41 ( ( if etagIsWeak et then
47 quoteStr (etagToken et) )
49 -- |Parse 'Etag' from an 'Ascii'. This functions throws an exception
51 parseETag ∷ Ascii → ETag
53 = let p = do et ← eTagP
56 bs = A.toByteString str
58 case parseOnly p bs of
60 Left err → error ("unparsable ETag: " ⧺ A.toString str ⧺ ": " ⧺ err)
62 -- |This is equivalent to @'ETag' 'Prelude.False'@. If you want to
63 -- generate an ETag from a file, try using
64 -- 'Network.HTTP.Lucu.StaticFile.generateETagFromFile'.
65 strongETag ∷ Ascii → ETag
66 strongETag = ETag False
68 -- |This is equivalent to @'ETag' 'Prelude.True'@.
69 weakETag ∷ Ascii → ETag
73 eTagP = do isWeak ← option False (string "W/" *> return True)
75 return $ ETag isWeak str
77 eTagListP ∷ Parser [ETag]
78 eTagListP = do xs ← listOf eTagP
80 fail "empty list of ETags"