Url Parsing in PureScript

Here’s the translation of the URL parsing example from Go to PureScript:

Our URL parsing program demonstrates how to parse and extract information from URLs in PureScript.

module Main where

import Prelude

import Data.Either (Either(..))
import Data.Maybe (Maybe(..))
import Effect (Effect)
import Effect.Console (log)
import URI (URI, parseURI)
import URI.Extra.QueryPairs (QueryPairs, parsePairs)
import URI.HostPortPair (HostPortPair, runHostPortPair)

main :: Effect Unit
main = do
  -- We'll parse this example URL, which includes a
  -- scheme, authentication info, host, port, path,
  -- query params, and query fragment.
  let s = "postgres://user:pass@host.com:5432/path?k=v#f"

  -- Parse the URL and ensure there are no errors.
  case parseURI s of
    Left err -> log $ "Error parsing URL: " <> show err
    Right u -> do
      -- Accessing the scheme is straightforward.
      log $ "Scheme: " <> show (URI.scheme u)

      -- User contains all authentication info
      case URI.userInfo u of
        Nothing -> log "No user info"
        Just userInfo -> do
          log $ "User info: " <> show userInfo
          log $ "Username: " <> show (URI.username userInfo)
          log $ "Password: " <> show (URI.password userInfo)

      -- The Host contains both the hostname and the port,
      -- if present.
      case URI.authority u of
        Nothing -> log "No authority"
        Just auth -> do
          let hostPort = runHostPortPair $ URI.hostPortPair auth
          log $ "Host: " <> show (URI.host hostPort)
          log $ "Port: " <> show (URI.port hostPort)

      -- Here we extract the path and the fragment after
      -- the #.
      log $ "Path: " <> show (URI.path u)
      log $ "Fragment: " <> show (URI.fragment u)

      -- To get query params in a string of k=v format,
      -- use query. You can also parse query params
      -- into a map.
      case URI.query u of
        Nothing -> log "No query"
        Just q -> do
          log $ "Raw query: " <> q
          case parsePairs q of
            Left err -> log $ "Error parsing query: " <> show err
            Right pairs -> do
              log $ "Parsed query: " <> show pairs
              log $ "Value of 'k': " <> show (lookup "k" pairs)

-- Helper function to lookup a key in QueryPairs
lookup :: String -> QueryPairs -> Maybe String
lookup key pairs = case filter (\(k, _) -> k == key) pairs of
  [(_, v)] -> Just v
  _ -> Nothing

Running our URL parsing program shows all the different pieces that we extracted:

Scheme: (Just "postgres")
User info: user:pass
Username: Just "user"
Password: Just "pass"
Host: "host.com"
Port: (Just 5432)
Path: "/path"
Fragment: (Just "f")
Raw query: k=v
Parsed query: [("k","v")]
Value of 'k': (Just "v")

This example demonstrates how to use the purescript-uri library to parse and extract information from URLs. The PureScript version uses a more functional approach with pattern matching and Maybe types to handle potential absence of data.

Note that unlike Go, PureScript doesn’t have built-in functions for URL parsing, so we use a third-party library. The concepts are similar, but the implementation details differ due to PureScript’s strong static typing and functional nature.