+{-# LANGUAGE
+ BangPatterns
+ , OverloadedStrings
+ , UnicodeSyntax
+ #-}
+
+-- |Manipulation of HTTP version string.
module Network.HTTP.Lucu.HttpVersion
( HttpVersion(..)
- , httpVersionP -- Parser HttpVersion
+ , httpVersionP
+ , printHttpVersion
)
where
+import qualified Blaze.Text.Int as BT
+import Control.Applicative
+import Control.Applicative.Unicode
+import Data.Ascii (AsciiBuilder)
+import qualified Data.Ascii as A
+import Data.Attoparsec.Char8
+import Data.Monoid.Unicode
+import Prelude hiding (min)
-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)
+-- |@'HttpVersion' major minor@ represents \"HTTP\/major.minor\".
+data HttpVersion
+ = HttpVersion !Int !Int
+ deriving (Eq, Show)
instance Ord HttpVersion where
(HttpVersion majA minA) `compare` (HttpVersion majB minB)
| minA < minB = LT
| otherwise = EQ
+httpVersionP ∷ Parser HttpVersion
+httpVersionP = string "HTTP/"
+ *>
+ choice [ string "1.1" *> pure (HttpVersion 1 1)
+ , string "1.0" *> pure (HttpVersion 1 0)
+ , HttpVersion <$> decimal ⊛ (char '.' *> decimal)
+ ]
-httpVersionP :: Parser HttpVersion
-httpVersionP = do string "HTTP/"
- major <- many1 digit
- char '.'
- minor <- many1 digit
- return $ HttpVersion (read major) (read minor)
-
+-- |Convert an 'HttpVersion' to 'AsciiBuilder'.
+printHttpVersion ∷ HttpVersion → AsciiBuilder
+printHttpVersion v
+ = case v of
+ -- 頻出するので高速化
+ HttpVersion 1 0 → A.toAsciiBuilder "HTTP/1.0"
+ HttpVersion 1 1 → A.toAsciiBuilder "HTTP/1.1"
+ -- 一般の場合
+ HttpVersion maj min
+ → A.toAsciiBuilder "HTTP/" ⊕
+ A.unsafeFromBuilder (BT.integral maj) ⊕
+ A.toAsciiBuilder "." ⊕
+ A.unsafeFromBuilder (BT.integral min)