{-# LANGUAGE FlexibleInstances , MultiParamTypeClasses , OverloadedStrings , TemplateHaskell , UnicodeSyntax #-} -- |An internal module for HTTP version numbers. module Network.HTTP.Lucu.HttpVersion ( HttpVersion(..) ) where import Control.Applicative import Control.Applicative.Unicode import Data.Ascii (Ascii, AsciiBuilder) import Data.Attoparsec.Char8 import Data.Attoparsec.Parsable import Data.ByteString (ByteString) import Data.Convertible.Base import Data.Convertible.Instances.Ascii () import Data.Convertible.Utils import Data.Monoid.Unicode import Prelude hiding (min) import Prelude.Unicode -- |An HTTP version consists of major and minor versions. data HttpVersion = HttpVersion !Int !Int deriving (Eq, Show) instance Ord HttpVersion where (HttpVersion majA minA) `compare` (HttpVersion majB minB) | majA > majB = GT | majA < majB = LT | minA > minB = GT | minA < minB = LT | otherwise = EQ instance ConvertSuccess HttpVersion Ascii where {-# INLINE convertSuccess #-} convertSuccess = convertSuccessVia ((⊥) ∷ AsciiBuilder) instance ConvertSuccess HttpVersion AsciiBuilder where {-# INLINE convertSuccess #-} convertSuccess v = case v of -- Optimisation for special cases. HttpVersion 1 0 → cs ("HTTP/1.0" ∷ Ascii) HttpVersion 1 1 → cs ("HTTP/1.1" ∷ Ascii) -- General (but almost never occuring) cases. HttpVersion maj min → cs ("HTTP/" ∷ Ascii) ⊕ convertUnsafe (show maj) ⊕ cs ("." ∷ Ascii) ⊕ convertUnsafe (show min) deriveAttempts [ ([t| HttpVersion |], [t| Ascii |]) , ([t| HttpVersion |], [t| AsciiBuilder |]) ] instance Parsable ByteString HttpVersion where {-# INLINEABLE parser #-} parser = string "HTTP/" *> (HttpVersion <$> decimal ⊛ (char '.' *> decimal))