module Data.URI.Internal.Scheme
( Scheme
, parser
, fromByteString
, toBuilder
)
where
import Blaze.ByteString.Builder (Builder)
import qualified Blaze.ByteString.Builder.ByteString as BB
#if defined(MIN_VERSION_QuickCheck)
import Control.Applicative
import Control.Applicative.Unicode
#endif
import Control.Failure
import Data.Attoparsec.Char8
import Data.CaseInsensitive as CI
import Data.Hashable
import Data.Monoid.Unicode
import Data.String
import Data.Semigroup
import Data.Typeable
import Data.URI.Internal ()
import Data.Vector.Storable.ByteString.Char8 (ByteString)
import qualified Data.Vector.Storable.ByteString.Char8 as C8
import Data.Vector.Storable.ByteString.Legacy
import Prelude hiding (takeWhile)
import Prelude.Unicode
#if defined(MIN_VERSION_QuickCheck)
import Test.QuickCheck.Arbitrary
import Test.QuickCheck.Gen
#endif
newtype Scheme = Scheme { unScheme ∷ CI ByteString }
deriving ( Eq
, FoldCase
, Hashable
, Ord
, Typeable
)
instance Show Scheme where
show = C8.unpack ∘ foldedCase ∘ unScheme
deriving instance IsString Scheme
instance Semigroup Scheme where
Scheme a <> Scheme b = Scheme (a ⊕ b)
parser ∷ Parser Scheme
parser = do x ← satisfy first
xs ← takeWhile nonFirst
return $ Scheme $ CI.mk $ x `C8.cons` fromLegacyByteString xs
<?>
"scheme"
where
first = isAlpha_ascii
nonFirst c
= isAlpha_ascii c ∨
isDigit c ∨
c ≡ '+' ∨
c ≡ '-' ∨
c ≡ '.'
toBuilder ∷ Scheme → Builder
toBuilder = BB.fromByteString ∘
toLegacyByteString ∘
foldedCase ∘
unScheme
fromByteString ∷ Failure String f ⇒ ByteString → f Scheme
fromByteString = either failure return ∘
parseOnly parser ∘
toLegacyByteString
#if defined(MIN_VERSION_QuickCheck)
instance Arbitrary Scheme where
arbitrary = (fromString ∘) ∘ (:) <$> x ⊛ xs
where
genAlpha = elements (['a'..'z'] ⊕ ['A'..'Z'])
genDigit = elements ['0'..'9']
genSym = elements ['+', '-', '.']
x = genAlpha
xs = listOf $ oneof [genAlpha, genDigit, genSym]
shrink = (fromString <$>) ∘ shr ∘ show ∘ unScheme
where
shr ∷ [Char] → [String]
shr [] = error "internal error"
shr (_:[]) = []
shr (x:y:ys) = (x:ys) : ((x:) <$> shr (y:ys))
instance CoArbitrary Scheme where
coarbitrary = coarbitrary ∘ show ∘ unScheme
#endif