Skip to content

Commit 07a0d88

Browse files
committed
Polish the docs for the URI module (#4710)
1 parent 01d3d8f commit 07a0d88

File tree

1 file changed

+80
-25
lines changed

1 file changed

+80
-25
lines changed

lib/elixir/lib/uri.ex

Lines changed: 80 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
defmodule URI do
22
@moduledoc """
3-
Utilities for working with and creating URIs.
3+
Utilities for working with URIs.
4+
5+
This module provides functions for working with URIs (for example, parsing
6+
URIs or encoding query strings). For reference, most of the functions in this
7+
module refer to [RFC 3986](https://tools.ietf.org/html/rfc3986).
48
"""
59

610
defstruct scheme: nil, path: nil, query: nil,
@@ -14,8 +18,9 @@ defmodule URI do
1418
@doc """
1519
Returns the default port for a given scheme.
1620
17-
If the scheme is unknown to URI, returns `nil`.
18-
Any scheme may be registered via `default_port/2`.
21+
If the scheme is unknown to the `URI` module, this function returns
22+
`nil`. The default port for any scheme can be configured globally
23+
via `default_port/2`.
1924
2025
## Examples
2126
@@ -31,10 +36,15 @@ defmodule URI do
3136
end
3237

3338
@doc """
34-
Registers a scheme with a default port.
39+
Registers the default port `port` for the given `scheme`.
40+
41+
After this function is called, `port` will be returned by
42+
`default_port/1` for the given scheme `scheme`. Note that this function
43+
changes the default port for the given `scheme` *globally*, meaning for
44+
every application.
3545
3646
It is recommended for this function to be invoked in your
37-
application start callback in case you want to register
47+
application's start callback in case you want to register
3848
new URIs.
3949
"""
4050
def default_port(scheme, port) when is_binary(scheme) and port > 0 do
@@ -44,9 +54,10 @@ defmodule URI do
4454
@doc """
4555
Encodes an enumerable into a query string.
4656
47-
Takes an enumerable (containing a sequence of two-element tuples)
48-
and returns a string in the form of `key1=value1&key2=value2...` where
49-
keys and values are URL encoded as per `encode_www_form/1`.
57+
Takes an enumerable that enumerates as a list of two-element
58+
tuples (e.g., a map or a keyword list) and returns a string
59+
in the form of `key1=value1&key2=value2...` where keys and
60+
values are URL encoded as per `encode_www_form/1`.
5061
5162
Keys and values can be any term that implements the `String.Chars`
5263
protocol, except lists which are explicitly forbidden.
@@ -61,15 +72,19 @@ defmodule URI do
6172
iex> URI.encode_query(query)
6273
"key=value+with+spaces"
6374
75+
iex> URI.encode_query %{key: [:a, :list]}
76+
** (ArgumentError) encode_query/1 values cannot be lists, got: [:a, :list]
77+
6478
"""
6579
def encode_query(l), do: Enum.map_join(l, "&", &pair/1)
6680

6781
@doc """
6882
Decodes a query string into a map.
6983
70-
Given a query string of the form of `key1=value1&key2=value2...`, produces a
71-
map with one entry for each key-value pair. Each key and value will be a
72-
binary. Keys and values will be percent-unescaped.
84+
Given a query string of the form of `key1=value1&key2=value2...`, this
85+
function inserts each key-value pair in the query string as one entry in the
86+
given `map`. Keys and values in the resulting map will be binaries. Keys and
87+
values will be percent-unescaped.
7388
7489
Use `query_decoder/1` if you want to iterate over each value manually.
7590
@@ -78,6 +93,9 @@ defmodule URI do
7893
iex> URI.decode_query("foo=1&bar=2")
7994
%{"bar" => "2", "foo" => "1"}
8095
96+
iex> URI.decode_query("percent=oh+yes%21", %{"starting" => "map"})
97+
%{"percent" => "oh yes!", "starting" => "map"}
98+
8199
"""
82100
def decode_query(q, map \\ %{})
83101

@@ -110,12 +128,14 @@ defmodule URI do
110128
end
111129

112130
@doc """
113-
Returns an iterator function over the query string that decodes
114-
the query string in steps.
131+
Returns a stream of two-element tuples representing key-value pairs in the
132+
given `query`.
133+
134+
Key and value in each tuple will be binaries and will be percent-unescaped.
115135
116136
## Examples
117137
118-
iex> URI.query_decoder("foo=1&bar=2") |> Enum.map(&(&1))
138+
iex> URI.query_decoder("foo=1&bar=2") |> Enum.to_list()
119139
[{"foo", "1"}, {"bar", "2"}]
120140
121141
"""
@@ -161,7 +181,14 @@ defmodule URI do
161181
@doc """
162182
Checks if the character is a "reserved" character in a URI.
163183
164-
Reserved characters are specified in [RFC3986, section 2.2](http://tools.ietf.org/html/rfc3986#section-2.2).
184+
Reserved characters are specified in
185+
[RFC 3986, section 2.2](http://tools.ietf.org/html/rfc3986#section-2.2).
186+
187+
## Examples
188+
189+
iex> URI.char_reserved?(?+)
190+
true
191+
165192
"""
166193
def char_reserved?(c) do
167194
c in ':/?#[]@!$&\'()*+,;='
@@ -170,7 +197,14 @@ defmodule URI do
170197
@doc """
171198
Checks if the character is a "unreserved" character in a URI.
172199
173-
Unreserved characters are specified in [RFC3986, section 2.3](http://tools.ietf.org/html/rfc3986#section-2.3).
200+
Unreserved characters are specified in
201+
[RFC 3986, section 2.3](http://tools.ietf.org/html/rfc3986#section-2.3).
202+
203+
## Examples
204+
205+
iex> URI.char_unreserved?(?_)
206+
true
207+
174208
"""
175209
def char_unreserved?(c) do
176210
c in ?0..?9 or
@@ -184,20 +218,33 @@ defmodule URI do
184218
185219
This is the default used by `URI.encode/2` where both
186220
reserved and unreserved characters are kept unescaped.
221+
222+
## Examples
223+
224+
iex> URI.char_unescaped?(?{)
225+
false
226+
187227
"""
188228
def char_unescaped?(c) do
189229
char_reserved?(c) or char_unreserved?(c)
190230
end
191231

192232
@doc """
193-
Percent-escapes a URI.
194-
Accepts `predicate` function as an argument to specify if char can be left as is.
233+
Percent-escapes the given string.
234+
235+
This function accepts a `predicate` function as an optional argument; if
236+
passed, this function will be called with each character (byte) in `str` as
237+
its argument and should return `true` if that character should not be escaped
238+
and left as is.
195239
196240
## Example
197241
198242
iex> URI.encode("ftp://s-ite.tld/?value=put it+й")
199243
"ftp://s-ite.tld/?value=put%20it+%D0%B9"
200244
245+
iex> URI.encode("a string", &(&1 != ?i))
246+
"a str%69ng"
247+
201248
"""
202249
def encode(str, predicate \\ &char_unescaped?/1) when is_binary(str) do
203250
for <<c <- str>>, into: "", do: percent(c, predicate)
@@ -287,14 +334,17 @@ defmodule URI do
287334
Parses a well-formed URI reference into its components.
288335
289336
Note this function expects a well-formed URI and does not perform
290-
any validation. See the examples section below of how `URI.parse/1`
291-
can be used to parse a wide range of relative URIs.
337+
any validation. See the "Examples" section below for examples of how
338+
`URI.parse/1` can be used to parse a wide range of URIs.
292339
293340
This function uses the parsing regular expression as defined
294-
in the [Appendix B of RFC3986](http://tools.ietf.org/html/rfc3986#appendix-B).
341+
in [RFC 3986, Appendix B](http://tools.ietf.org/html/rfc3986#appendix-B).
342+
343+
When a URI is given without a port, the value returned by
344+
`URI.default_port/1` for the URI's scheme is used for the `:port` field.
295345
296-
When a URI is given without a port, the values registered via
297-
`URI.default_port/1` and `URI.default_port/2` are used.
346+
If a `%URI{}` struct is given to this function, this function returns it
347+
unmodified.
298348
299349
## Examples
300350
@@ -360,17 +410,22 @@ defmodule URI do
360410
end
361411

362412
@doc """
363-
Converts the URI to string.
413+
Returns the string representation of the given `URI` struct.
364414
365415
iex> URI.to_string(URI.parse("http://google.com"))
366416
"http://google.com"
417+
418+
iex> URI.to_string(%URI{scheme: "foo", host: "bar.baz"})
419+
"foo://bar.baz"
420+
367421
"""
368422
defdelegate to_string(uri), to: String.Chars.URI
369423

370424
@doc ~S"""
371425
Merges two URIs.
372426
373-
This function merges two URIs as per [RFC3986, section 5.2](http://tools.ietf.org/html/rfc3986#section-5.2).
427+
This function merges two URIs as per
428+
[RFC 3986, section 5.2](http://tools.ietf.org/html/rfc3986#section-5.2).
374429
375430
## Examples
376431

0 commit comments

Comments
 (0)