1#pragma once
2
3#include <pw_types.h>
4
5#ifdef __cplusplus
6extern "C" {
7#endif
8
9/*
10 * https://datatracker.ietf.org/doc/html/rfc3986 Uniform Resource Identifier (URI): Generic Syntax
11 * https://datatracker.ietf.org/doc/html/rfc1738 Uniform Resource Locators (URL)
12 */
13
14#define pw_parse_uri(uri, result, allow_spaces) _Generic((uri), \
15 PwStringIter*: _pw_parse_uri_iter, \
16 PwValuePtr: _pw_parse_uri_pw \
17 )((uri), (result), (allow_spaces))
18
19[[nodiscard]] bool _pw_parse_uri_iter(PwStringIter* uri, PwValuePtr result, bool allow_spaces);
20[[nodiscard]] bool _pw_parse_uri_pw(PwValuePtr uri, PwValuePtr result, bool allow_spaces);
21/*
22 * Parse `uri` into parts. The result is a map containing the following keys:
23 * - scheme: string, e.g. http, ftp, gopher, etc.
24 * - user: string
25 * - password: string
26 * - host: string
27 * - port: unsigned
28 * - path: string
29 * - query: map containing key=value pairs
30 * - fragment: string
31 *
32 * Any or all components can be Null if unspecified.
33 *
34 * If `allow_spaces` is true, spaces are allowed in the path component.
35 *
36 * All components are properly decoded, including host IDNA
37 * Non-ASCII printable characters (codepoint > 127) and spaces (if `allow_spaces` is true)
38 * are allowed in `uri` as if they were pct-encoded.
39 *
40 * This function does not perform path normalization.
41 *
42 * Upon exit, the iterator may point to a delimiter character which is not a part of URI syntax.
43 */
44
45#define pw_parse_uri_query(query, result) _Generic((query), \
46 PwStringIter*: _pw_parse_uri_query_iter, \
47 PwValuePtr: _pw_parse_uri_query_pw \
48 )((query), (result))
49
50[[nodiscard]] bool _pw_parse_uri_query_iter(PwStringIter* query, PwValuePtr result);
51[[nodiscard]] bool _pw_parse_uri_query_pw(PwValuePtr query, PwValuePtr result);
52/*
53 * Parse query part of the URI.
54 */
55
56[[nodiscard]] bool pw_join_uri(PwValuePtr base_uri, PwValuePtr other_uri, PwValuePtr result);
57/*
58 * Join `base_uri` with `other_uri`. URIs can be strings or maps, as a result of `pw_parse_uri`.
59 * `other_uri` can be a list which is treated as path (absolute paths start from '/').
60 * If paths of URIs are absolute, schemes must be the same. As an exception, they can be http and https,
61 * the result will inherit `base_uri` scheme.
62 *
63 * The result is always a map, as in `pw_parse_uri`
64 */
65
66[[nodiscard]] bool pw_uri_to_string(PwValuePtr uri, PwValuePtr unescaped_result, PwValuePtr escaped_result);
67/*
68 * Join `uri` parts to string.
69 * If `unescaped_result` is provided (not nullptr) then it receives unescaped URI with any character size.
70 * If `escaped_result` is provided, it receives escaped URI where host is encoded in IDNA
71 * and all the rest parts are encoded in UTF-8 and percent-escaped.
72 * The size of character of the `escaped_result` is always 1.
73 */
74
75#ifdef __cplusplus
76}
77#endif