4 , GeneralizedNewtypeDeriving
5 , MultiParamTypeClasses
11 module Data.URI.Internal.Scheme
15 import Data.Ascii (AsciiBuilder, CIAscii)
16 import qualified Data.Ascii as A
17 import Data.Attoparsec.Char8
18 import qualified Data.ByteString.Char8 as BS
19 import Data.CaseInsensitive
20 import Data.Convertible.Base
24 import Data.URI.Internal
26 import Prelude hiding (takeWhile)
27 import Prelude.Unicode
29 -- |'Scheme' names consist of a non-empty sequence of characters
30 -- beginning with a letter and followed by any combination of letters,
31 -- digits, plus (\'+\'), period (\'.\'), or hyphen (\'-\'). Comparison
32 -- of 'Scheme's are always case-insensitive. See:
33 -- <http://tools.ietf.org/html/rfc3986#section-3.1>
34 newtype Scheme = Scheme CIAscii
43 -- |'fromString' is a fast but unsafe way to create 'Scheme' such that
44 -- no validation on the string is performed.
45 deriving instance IsString Scheme
47 instance Default (Parser Scheme) where
48 {-# INLINEABLE def #-}
49 def = do x ← satisfy first
50 xs ← takeWhile nonFirst
51 return ∘ fromBS $ x `BS.cons` xs
57 {-# INLINE nonFirst #-}
65 fromBS = Scheme ∘ A.toCIAscii ∘ A.unsafeFromByteString
67 instance ConvertSuccess Scheme CIAscii where
68 {-# INLINE convertSuccess #-}
69 convertSuccess (Scheme s) = foldCase s
71 instance ConvertSuccess Scheme AsciiBuilder where
72 {-# INLINE convertSuccess #-}
73 convertSuccess = A.toAsciiBuilder ∘ A.fromCIAscii ∘ cs
75 instance ConvertAttempt CIAscii Scheme where
76 {-# INLINE convertAttempt #-}
77 convertAttempt = parseAttempt' def ∘ A.fromCIAscii
79 deriveAttempts [ ([t| Scheme |], [t| AsciiBuilder |])
80 , ([t| Scheme |], [t| CIAscii |])