# Modern URI
[](http://opensource.org/licenses/BSD-3-Clause)
[](https://hackage.haskell.org/package/modern-uri)
[](http://stackage.org/nightly/package/modern-uri)
[](http://stackage.org/lts/package/modern-uri)
[](https://travis-ci.org/mrkkrp/modern-uri)
[](https://coveralls.io/github/mrkkrp/modern-uri?branch=master)
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`](https://hackage.haskell.org/package/uri),
[`network-uri`](https://hackage.haskell.org/package/network-uri), and
[`uri-bytestring`](https://hackage.haskell.org/package/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 `URI`s, 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](https://github.com/mrkkrp/modern-uri/issues).
Pull requests are also welcome and will be reviewed quickly.
## License
Copyright © 2017 Mark Karpov
Distributed under BSD 3 clause license.