BSD-3-Clause licensed and maintained by Mark Karpov
This version can be pinned in stack with:modern-uri-0.0.2.0@sha256:2741a905a6bdb4f16d3d5dcd06087b94da52df45329ca10ffb7da8203927af7c,3938

Module documentation for 0.0.2.0

Modern URI

License BSD3 Hackage Stackage Nightly Stackage LTS Build Status Coverage Status

This is a modern library for working with URIs in Haskell as per RFC 3986:

https://tools.ietf.org/html/rfc3986

Motivation

There are already at least three libraries for working with URIs: uri, network-uri, and uri-bytestring. Why write one more?

Let’s see first about the uri and network-uri packages (they are quite similar):

  • They use String instead of Text or ByteString, this is inefficient.
  • The types are not very precise. Query string is represented as Maybe String for example.
  • The packages use Parsec under the hood, however they do not allow us to use its URI parser in a bigger Parsec parser.

Now what about uri-bytestring?

  • Works with ByteString, which totally makes sense because a URI can have only ASCII characters in it. However sometimes a URI is a part of a bigger document that can contain Unicode characters and so we may need to parse a URI from Text or render it to Text. Ideally, we would like to be able to parse from both Text and ByteString as well to render to both Text and ByteString.
  • Does not allow to use its URI parser as part of a bigger parser.
  • Provides newtype wrappers for different components of URI, but we could still put something incorrect inside.
  • Absolute and relative URI references have different types, which may or may not be handy.
  • Provides lenses, but does not provide e.g. traversal for working with query parameters selected by their names.

Features

The modern-uri package features:

  • Correct by construction URI data type. Correctness is ensured by guaranteeing that every sub-component of the URI record is by itself cannot be invalid. This boils down to careful use of types and a set of smart constructors for things like scheme, host, etc.
  • Textual components in the URI data type represented as Text rather than ByteString, because they are percent-decoded and so they can contain characters outside of ASCII range (i.e. Unicode). This allows for easier manipulation of URIs, while encoding and decoding headaches are handled by the parsers and renders for you.
  • Absolute and relative URIs differ only by the scheme component: if it’s Nothing, then URI is relative, otherwise it’s absolute.
  • Megaparsec parser that can be used as a standalone smart constructor for the URI data type (see mkURI) as well as be seamlessly integrated into a bigger Megaparsec parser that consumes strict Text (see parser) or strict ByteString (see parserBs).
  • The parser performs some normalization, for example it collapses consecutive slashes. Some smart constructors such as mkScheme and mkHost also perform normalization. So in a sense URIs are also “normalized by construction” to some extent.
  • Fast rendering to strict Text and ByteString as well as to their respective Builder types and to String/ShowS.
  • Extensive set of lensy helpers for easier manipulation of the nested data types (see Text.URI.Lens).
  • Quasi-quoters for compile-time construction of the URI data type and refined text types (see Text.URI.QQ).

Contribution

Issues, bugs, and questions may be reported in the GitHub issue tracker for this project.

Pull requests are also welcome and will be reviewed quickly.

License

Copyright © 2017 Mark Karpov

Distributed under BSD 3 clause license.

Changes

Modern URI 0.0.2.0

  • Added the renderStr and renderStr' functions for efficient rendering to String and ShowS.

  • Added the parserBs that can consume strict ByteString streams.

Modern URI 0.0.1.0

  • Initial release.