{-# LANGUAGE DeriveDataTypeable , OverloadedStrings , RecordWildCards , TemplateHaskell , UnicodeSyntax #-} -- |Parsing and printing MIME Media Types -- (). module Network.HTTP.Lucu.MIMEType ( MIMEType(..) , parseMIMEType , printMIMEType , mimeType , mimeTypeList ) where import Control.Applicative import Data.Ascii (Ascii, AsciiBuilder, CIAscii) import qualified Data.Ascii as A import Data.Attoparsec.Char8 as P import Data.Convertible.Base import Data.Convertible.Instances.Ascii () import Data.Convertible.Utils import Data.Monoid.Unicode import Data.Typeable import Language.Haskell.TH.Syntax import Network.HTTP.Lucu.MIMEParams import Network.HTTP.Lucu.OrphanInstances () import Network.HTTP.Lucu.Parser import Network.HTTP.Lucu.Parser.Http import Prelude.Unicode -- |A media type, subtype, and parameters. data MIMEType = MIMEType { mtMedia ∷ !CIAscii , mtSub ∷ !CIAscii , mtParams ∷ !MIMEParams } deriving (Eq, Show, Read, Typeable) instance Lift MIMEType where lift (MIMEType {..}) = [| MIMEType { mtMedia = $(lift mtMedia ) , mtSub = $(lift mtSub ) , mtParams = $(lift mtParams) } |] -- |Convert a 'MIMEType' to an 'AsciiBuilder'. printMIMEType ∷ MIMEType → AsciiBuilder {-# INLINEABLE printMIMEType #-} printMIMEType (MIMEType {..}) = A.toAsciiBuilder (A.fromCIAscii mtMedia) ⊕ A.toAsciiBuilder "/" ⊕ A.toAsciiBuilder (A.fromCIAscii mtSub) ⊕ cs mtParams -- |Parse 'MIMEType' from an 'Ascii'. This function throws an -- exception for parse error. For literals consider using -- 'Network.HTTP.Lucu.MIMEType.TH.mimeType'. parseMIMEType ∷ Ascii → MIMEType {-# INLINEABLE parseMIMEType #-} parseMIMEType str = case parseOnly (finishOff mimeType) $ A.toByteString str of Right t → t Left err → error ("Unparsable MIME Type: " ⧺ A.toString str ⧺ ": " ⧺ err) -- |'Parser' for an 'MIMEType'. mimeType ∷ Parser MIMEType {-# INLINEABLE mimeType #-} mimeType = do media ← A.toCIAscii <$> token _ ← char '/' sub ← A.toCIAscii <$> token params ← mimeParams return $ MIMEType media sub params -- |'Parser' for a list of 'MIMEType's. mimeTypeList ∷ Parser [MIMEType] {-# INLINE mimeTypeList #-} mimeTypeList = listOf mimeType