[web-devel] Re: ANN: Salvia-1.0.0
Gregory Collins
greg at gregorycollins.net
Tue Mar 23 17:22:05 EDT 2010
Michael Snoyman <michael at snoyman.com> writes:
> * "Request and response headers should have case-insensitive match for
> the Eq instance." I'm thinking that this is the correct approach to
> take, and would like input on it. (Thanks Gregory.
Here's our (dead simple) code for this:
------------------------------------------------------------------------
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.CIByteString
( CIByteString
, toCI
, unCI
) where
-- for IsString instance
import Data.ByteString.Char8 ()
import Data.ByteString (ByteString)
import Data.ByteString.Internal (c2w, w2c)
import qualified Data.ByteString as S
import Data.Char
import Data.String
-- | A case-insensitive newtype wrapper for ByteString
data CIByteString = CIByteString { unCI :: !ByteString
, _lowercased :: !ByteString }
toCI :: ByteString -> CIByteString
toCI s = CIByteString s t
where
t = lowercase s
instance Show CIByteString where
show (CIByteString s _) = show s
lowercase :: ByteString -> ByteString
lowercase = S.map (c2w . toLower . w2c)
instance Eq CIByteString where
(CIByteString _ a) == (CIByteString _ b) = a == b
(CIByteString _ a) /= (CIByteString _ b) = a /= b
instance Ord CIByteString where
(CIByteString _ a) <= (CIByteString _ b) = a <= b
instance IsString CIByteString where
fromString = toCI . fromString
------------------------------------------------------------------------
Note that we store the downcased version in the datatype, otherwise
Eq/Ord has to perform the downcase a zillion times, only to throw it
away afterwards. Note also that we ignore any encoding issues -- we can
get away w/ this because HTTP header names are constrained by the
protocol to be ASCII-only.
This datatype also has an "IsString" instance so you can use string
literals with "{-# LANGUAGE OverloadedStrings #-}" turned on.
G.
--
Gregory Collins <greg at gregorycollins.net>
More information about the web-devel
mailing list