{-# LANGUAGE DeriveDataTypeable , FlexibleInstances , GeneralizedNewtypeDeriving , MultiParamTypeClasses , StandaloneDeriving , TemplateHaskell , TypeSynonymInstances , UnicodeSyntax #-} module Data.URI.Internal.Scheme ( Scheme ) where import Data.Ascii (AsciiBuilder, CIAscii) import qualified Data.Ascii as A import Data.Attoparsec.Char8 import qualified Data.ByteString.Char8 as BS import Data.CaseInsensitive import Data.Convertible.Base import Data.Default import Data.Hashable import Data.String import Data.URI.Internal import Data.Typeable import Prelude hiding (takeWhile) import Prelude.Unicode -- |'Scheme' names consist of a non-empty sequence of characters -- beginning with a letter and followed by any combination of letters, -- digits, plus (\'+\'), period (\'.\'), or hyphen (\'-\'). Comparison -- of 'Scheme's are always case-insensitive. See: -- newtype Scheme = Scheme CIAscii deriving ( Eq , FoldCase , Hashable , Ord , Show , Typeable ) -- |'fromString' is a fast but unsafe way to create 'Scheme' such that -- no validation on the string is performed. deriving instance IsString Scheme instance Default (Parser Scheme) where {-# INLINEABLE def #-} def = do x ← satisfy first xs ← takeWhile nonFirst return ∘ fromBS $ x `BS.cons` xs "scheme" where {-# INLINE first #-} first = isAlpha_ascii {-# INLINE nonFirst #-} nonFirst c = isAlpha_ascii c ∨ isDigit c ∨ c ≡ '+' ∨ c ≡ '-' ∨ c ≡ '.' {-# INLINE fromBS #-} fromBS = Scheme ∘ A.toCIAscii ∘ A.unsafeFromByteString -- |Extract a 'CIAscii' with all letters lowercased. instance ConvertSuccess Scheme CIAscii where {-# INLINE convertSuccess #-} convertSuccess (Scheme s) = foldCase s -- |Create an 'AsciiBuilder' with all letters lowercased. instance ConvertSuccess Scheme AsciiBuilder where {-# INLINE convertSuccess #-} convertSuccess = A.toAsciiBuilder ∘ A.fromCIAscii ∘ cs -- |Try to parse a 'Scheme' from 'CIAscii'. instance ConvertAttempt CIAscii Scheme where {-# INLINE convertAttempt #-} convertAttempt = parseAttempt' def ∘ A.fromCIAscii deriveAttempts [ ([t| Scheme |], [t| AsciiBuilder |]) , ([t| Scheme |], [t| CIAscii |]) ]