content: {-# LANGUAGE FlexibleInstances #-}
  {-# OPTIONS_GHC -fno-warn-orphans #-}
  
  module URI.ByteString.Extension where
  
  import Data.ByteString (ByteString)
  import Data.String (IsString (..))
  import Data.Text (Text)
  import Data.Text.Encoding (decodeUtf8, encodeUtf8)
  import Lens.Micro
  
  import qualified Data.ByteString.Char8 as C8
  
  import URI.ByteString
  
  instance IsString Scheme where
    fromString = Scheme . fromString
  
  instance IsString Host where
    fromString = Host . fromString
  
  instance IsString (URIRef Absolute) where
    fromString =
      either (error . show) id . parseURI strictURIParserOptions . C8.pack
  
  instance IsString (URIRef Relative) where
    fromString =
      either (error . show) id . parseRelativeRef strictURIParserOptions . C8.pack
  
  fromText :: Text -> Maybe URI
  fromText =
    either (const Nothing) Just . parseURI strictURIParserOptions . encodeUtf8
  
  unsafeFromText :: Text -> URI
  unsafeFromText =
    either (error . show) id . parseURI strictURIParserOptions . encodeUtf8
  
  toText :: URI -> Text
  toText = decodeUtf8 . serializeURIRef'
  
  fromRelative :: Scheme -> Host -> RelativeRef -> URI
  fromRelative s h = flip withHost h . toAbsolute s
  
  withHost :: URIRef a -> Host -> URIRef a
  withHost u h =
    u
      & authorityL
        %~ maybe
          (Just $ Authority Nothing h Nothing)
          (\a -> Just $ a & authorityHostL .~ h)
  
  withPath :: URIRef a -> ByteString -> URIRef a
  withPath u p = u & pathL .~ p
  
  withQuery :: URIRef a -> [(ByteString, ByteString)] -> URIRef a
  withQuery u q = u & (queryL . queryPairsL) %~ (++ q)
  