+{-# LANGUAGE
+ FlexibleInstances
+ , MultiParamTypeClasses
+ , OverloadedStrings
+ , TemplateHaskell
+ , TypeSynonymInstances
+ , UnicodeSyntax
+ #-}
+-- |An internal module for HTTP version numbers.
module Network.HTTP.Lucu.HttpVersion
( HttpVersion(..)
- , httpVersionP -- Parser HttpVersion
)
where
+import Control.Applicative
+import Control.Applicative.Unicode
+import Data.Ascii (Ascii, AsciiBuilder)
+import Data.Attoparsec.Char8
+import Data.Convertible.Base
+import Data.Convertible.Instances.Ascii ()
+import Data.Convertible.Utils
+import Data.Default
+import Data.Monoid.Unicode
+import Prelude hiding (min)
+import Prelude.Unicode
-import qualified Data.ByteString.Lazy.Char8 as B
-import Data.ByteString.Lazy.Char8 (ByteString)
-import Network.HTTP.Lucu.Parser
-
-data HttpVersion = HttpVersion Int Int
- deriving (Show, Eq)
+-- |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)
| 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)
-httpVersionP :: Parser HttpVersion
-httpVersionP = do string "HTTP/"
- major <- many1 digit
- char '.'
- minor <- many1 digit
- return $ HttpVersion (read major) (read minor)
+deriveAttempts [ ([t| HttpVersion |], [t| Ascii |])
+ , ([t| HttpVersion |], [t| AsciiBuilder |])
+ ]
+instance Default (Parser HttpVersion) where
+ {-# INLINEABLE def #-}
+ def = string "HTTP/"
+ *>
+ (HttpVersion <$> decimal ⊛ (char '.' *> decimal))