content: {-# LANGUAGE OverloadedStrings #-}
  
  module Main (main) where
  
  import Criterion.Main
  import Data.ByteString (ByteString)
  import Data.Maybe (fromJust)
  import Data.String (IsString (..))
  import Data.Text (Text)
  import Data.Void
  import Text.Megaparsec
  import Text.URI (URI)
  import Text.URI qualified as URI
  
  main :: IO ()
  main =
    defaultMain
      [ bparser turiStr,
        bparserBs turiStr,
        brender turi,
        brenderBs turi,
        brenderStr turi
      ]
  
  ----------------------------------------------------------------------------
  -- Helpers
  
  -- | Test 'URI' as a polymorphic string.
  turiStr :: (IsString a) => a
  turiStr = "https://mark:secret@github.com:443/mrkkrp/modern-uri?foo=bar#fragment"
  
  -- | Test 'URI' in parsed form.
  turi :: URI
  turi = fromJust (URI.mkURI turiStr)
  
  -- | Benchmark speed of the 'URI' parser with given input.
  bparser :: Text -> Benchmark
  bparser txt = env (return txt) (bench "text parser" . nf p)
    where
      p = parse (URI.parser <* eof :: Parsec Void Text URI) ""
  
  -- | Like 'bparser' but accepts a 'ByteString'.
  bparserBs :: ByteString -> Benchmark
  bparserBs bs = env (return bs) (bench "bs parser" . nf p)
    where
      p = parse (URI.parserBs <* eof :: Parsec Void ByteString URI) ""
  
  -- | Benchmark speed of the 'URI' render with given input.
  brender :: URI -> Benchmark
  brender uri = env (return uri) (bench "text render" . nf URI.render)
  
  -- | The same as 'brender' but for the 'URI.renderBs' render.
  brenderBs :: URI -> Benchmark
  brenderBs uri = env (return uri) (bench "bs render" . nf URI.renderBs)
  
  -- | The same as 'brender' but for the 'URI.renderString' render.
  brenderStr :: URI -> Benchmark
  brenderStr uri = env (return uri) (bench "str render" . nf URI.renderStr)
  