6 -- |Manipulation of MIME Types.
7 module Network.HTTP.Lucu.MIMEType
18 import Control.Applicative
19 import Data.Ascii (Ascii, AsciiBuilder, CIAscii)
20 import qualified Data.Ascii as A
21 import Data.Attoparsec.Char8 as P
23 import Data.Monoid.Unicode
24 import Data.Text (Text)
25 import Network.HTTP.Lucu.Parser.Http
26 import Network.HTTP.Lucu.RFC2231
27 import Prelude hiding (min)
28 import Prelude.Unicode
30 -- |@'MIMEType' \"major\" \"minor\" [(\"name\", \"value\")]@
31 -- represents \"major\/minor; name=value\".
32 data MIMEType = MIMEType {
35 , mtParams ∷ !(Map CIAscii Text)
38 -- |Construct a 'MIMEType' without any parameters.
39 mkMIMEType ∷ CIAscii → CIAscii → MIMEType
40 {-# INLINE mkMIMEType #-}
42 = MIMEType maj min (∅)
44 -- |Convert a 'MIMEType' to 'AsciiBuilder'.
45 printMIMEType ∷ MIMEType → AsciiBuilder
46 {-# INLINEABLE printMIMEType #-}
47 printMIMEType (MIMEType maj min params)
48 = A.toAsciiBuilder (A.fromCIAscii maj) ⊕
49 A.toAsciiBuilder "/" ⊕
50 A.toAsciiBuilder (A.fromCIAscii min) ⊕
53 -- |Parse 'MIMEType' from an 'Ascii'. This function throws an
54 -- exception for parse error.
55 parseMIMEType ∷ Ascii → MIMEType
56 {-# INLINEABLE parseMIMEType #-}
58 = case parseOnly p $ A.toByteString str of
60 Left err → error ("unparsable MIME Type: " ⧺ A.toString str ⧺ ": " ⧺ err)
68 mimeTypeP ∷ Parser MIMEType
69 {-# INLINEABLE mimeTypeP #-}
70 mimeTypeP = do maj ← A.toCIAscii <$> token
72 min ← A.toCIAscii <$> token
74 return $ MIMEType maj min params
76 mimeTypeListP ∷ Parser [MIMEType]
77 {-# INLINE mimeTypeListP #-}
78 mimeTypeListP = listOf mimeTypeP