Skip to content

Commit c28a768

Browse files
authored
Minor misc revisions to URITemplate (#2154)
Signed-off-by: Juan Cruz Viotti <[email protected]>
1 parent 90fa639 commit c28a768

File tree

5 files changed

+220
-164
lines changed

5 files changed

+220
-164
lines changed

src/core/uritemplate/CMakeLists.txt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME uritemplate
2-
PRIVATE_HEADERS error.h
3-
SOURCES
4-
helpers.h
5-
uritemplate.cc)
2+
PRIVATE_HEADERS error.h token.h
3+
SOURCES helpers.h uritemplate.cc)
64

75
if(SOURCEMETA_CORE_INSTALL)
86
sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME uritemplate)

src/core/uritemplate/include/sourcemeta/core/uritemplate.h

Lines changed: 6 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,17 @@
77

88
// NOLINTBEGIN(misc-include-cleaner)
99
#include <sourcemeta/core/uritemplate_error.h>
10+
#include <sourcemeta/core/uritemplate_token.h>
1011
// NOLINTEND(misc-include-cleaner)
1112

1213
#include <cstddef> // std::size_t
13-
#include <cstdint> // std::uint64_t, std::uint16_t
14+
#include <cstdint> // std::uint64_t
1415
#include <functional> // std::function
1516
#include <optional> // std::optional
1617
#include <string> // std::string
1718
#include <string_view> // std::string_view
1819
#include <tuple> // std::tuple
1920
#include <type_traits> // std::void_t
20-
#include <variant> // std::variant
2121
#include <vector> // std::vector
2222

2323
/// @defgroup uritemplate URI Template
@@ -36,167 +36,12 @@ namespace sourcemeta::core {
3636
using URITemplateValue = std::optional<
3737
std::tuple<std::string_view, std::optional<std::string_view>, bool>>;
3838

39-
#ifndef DOXYGEN
40-
struct URITemplateTokenLiteral;
41-
struct URITemplateTokenVariable;
42-
struct URITemplateTokenReservedExpansion;
43-
struct URITemplateTokenFragmentExpansion;
44-
struct URITemplateTokenLabelExpansion;
45-
struct URITemplateTokenPathExpansion;
46-
struct URITemplateTokenPathParameterExpansion;
47-
struct URITemplateTokenQueryExpansion;
48-
struct URITemplateTokenQueryContinuationExpansion;
49-
#endif
50-
51-
/// @ingroup uritemplate
52-
/// A token in a parsed URI Template
53-
using URITemplateToken = std::variant<
54-
URITemplateTokenLiteral, URITemplateTokenVariable,
55-
URITemplateTokenReservedExpansion, URITemplateTokenFragmentExpansion,
56-
URITemplateTokenLabelExpansion, URITemplateTokenPathExpansion,
57-
URITemplateTokenPathParameterExpansion, URITemplateTokenQueryExpansion,
58-
URITemplateTokenQueryContinuationExpansion>;
59-
6039
/// @ingroup uritemplate
6140
/// The result of parsing a token: the token and how many characters were
6241
/// consumed
6342
using URITemplateParseResult =
6443
std::optional<std::pair<URITemplateToken, std::size_t>>;
6544

66-
// Exporting symbols that depends on the standard C++ library is considered
67-
// safe.
68-
// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN
69-
#if defined(_MSC_VER)
70-
#pragma warning(push)
71-
#pragma warning(disable : 4251)
72-
#endif
73-
74-
/// @ingroup uritemplate
75-
/// A literal string segment in a URI Template
76-
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenLiteral {
77-
std::string_view value;
78-
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
79-
char delimiter) const noexcept -> std::size_t;
80-
};
81-
82-
/// @ingroup uritemplate
83-
/// A variable specification within a URI Template expression
84-
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateVariableSpecification {
85-
std::string_view name;
86-
// As per the RFC, the range is 1-9999. 0 means "no prefix length"
87-
std::uint16_t length{0};
88-
bool explode{false};
89-
};
90-
91-
/// @ingroup uritemplate
92-
/// A simple string variable expansion {var} in a URI Template (Level 1)
93-
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenVariable {
94-
std::vector<URITemplateVariableSpecification> variables;
95-
static constexpr char separator = ',';
96-
static constexpr bool named = false;
97-
static constexpr bool allow_reserved = false;
98-
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
99-
char delimiter) const noexcept -> std::size_t;
100-
};
101-
102-
/// @ingroup uritemplate
103-
/// A reserved expansion {+var} in a URI Template (Level 2)
104-
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenReservedExpansion {
105-
std::vector<URITemplateVariableSpecification> variables;
106-
static constexpr char op = '+';
107-
static constexpr char separator = ',';
108-
static constexpr bool named = false;
109-
static constexpr bool allow_reserved = true;
110-
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
111-
char delimiter) const noexcept -> std::size_t;
112-
};
113-
114-
/// @ingroup uritemplate
115-
/// A fragment expansion {#var} in a URI Template (Level 2)
116-
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenFragmentExpansion {
117-
std::vector<URITemplateVariableSpecification> variables;
118-
static constexpr char op = '#';
119-
static constexpr char separator = ',';
120-
static constexpr char prefix = '#';
121-
static constexpr bool named = false;
122-
static constexpr bool allow_reserved = true;
123-
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
124-
char delimiter) const noexcept -> std::size_t;
125-
};
126-
127-
/// @ingroup uritemplate
128-
/// A label expansion {.var} in a URI Template (Level 3)
129-
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenLabelExpansion {
130-
std::vector<URITemplateVariableSpecification> variables;
131-
static constexpr char op = '.';
132-
static constexpr char separator = '.';
133-
static constexpr char prefix = '.';
134-
static constexpr bool named = false;
135-
static constexpr bool allow_reserved = false;
136-
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
137-
char delimiter) const noexcept -> std::size_t;
138-
};
139-
140-
/// @ingroup uritemplate
141-
/// A path expansion {/var} in a URI Template (Level 3)
142-
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenPathExpansion {
143-
std::vector<URITemplateVariableSpecification> variables;
144-
static constexpr char op = '/';
145-
static constexpr char separator = '/';
146-
static constexpr char prefix = '/';
147-
static constexpr bool named = false;
148-
static constexpr bool allow_reserved = false;
149-
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
150-
char delimiter) const noexcept -> std::size_t;
151-
};
152-
153-
/// @ingroup uritemplate
154-
/// A path parameter expansion {;var} in a URI Template (Level 3)
155-
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT
156-
URITemplateTokenPathParameterExpansion {
157-
std::vector<URITemplateVariableSpecification> variables;
158-
static constexpr char op = ';';
159-
static constexpr char separator = ';';
160-
static constexpr char prefix = ';';
161-
static constexpr bool named = true;
162-
static constexpr bool allow_reserved = false;
163-
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
164-
char delimiter) const noexcept -> std::size_t;
165-
};
166-
167-
/// @ingroup uritemplate
168-
/// A query expansion {?var} in a URI Template (Level 3)
169-
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenQueryExpansion {
170-
std::vector<URITemplateVariableSpecification> variables;
171-
static constexpr char op = '?';
172-
static constexpr char separator = '&';
173-
static constexpr char prefix = '?';
174-
static constexpr bool named = true;
175-
static constexpr bool allow_reserved = false;
176-
static constexpr char empty_suffix = '=';
177-
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
178-
char delimiter) const noexcept -> std::size_t;
179-
};
180-
181-
/// @ingroup uritemplate
182-
/// A query continuation expansion {&var} in a URI Template (Level 3)
183-
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT
184-
URITemplateTokenQueryContinuationExpansion {
185-
std::vector<URITemplateVariableSpecification> variables;
186-
static constexpr char op = '&';
187-
static constexpr char separator = '&';
188-
static constexpr char prefix = '&';
189-
static constexpr bool named = true;
190-
static constexpr bool allow_reserved = false;
191-
static constexpr char empty_suffix = '=';
192-
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
193-
char delimiter) const noexcept -> std::size_t;
194-
};
195-
196-
#if defined(_MSC_VER)
197-
#pragma warning(pop)
198-
#endif
199-
20045
/// @ingroup uritemplate
20146
/// A parsed URI Template per RFC 6570. This class behaves like a view. The
20247
/// source string must outlive the template
@@ -219,7 +64,10 @@ class SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplate {
21964
[[nodiscard]] auto empty() const noexcept -> bool;
22065

22166
/// Get the token at the given index
222-
[[nodiscard]] auto at(std::size_t index) const -> const URITemplateToken &;
67+
[[nodiscard]] auto at(std::size_t index) const & -> const URITemplateToken &;
68+
69+
/// Get the token at the given index (move overload)
70+
[[nodiscard]] auto at(std::size_t index) && -> URITemplateToken;
22371

22472
/// Iterator to the beginning of the tokens
22573
[[nodiscard]] auto begin() const noexcept
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#ifndef SOURCEMETA_CORE_URITEMPLATE_TOKEN_H_
2+
#define SOURCEMETA_CORE_URITEMPLATE_TOKEN_H_
3+
4+
#ifndef SOURCEMETA_CORE_URITEMPLATE_EXPORT
5+
#include <sourcemeta/core/uritemplate_export.h>
6+
#endif
7+
8+
#include <cstddef> // std::size_t
9+
#include <cstdint> // std::uint16_t
10+
#include <string_view> // std::string_view
11+
#include <variant> // std::variant
12+
#include <vector> // std::vector
13+
14+
namespace sourcemeta::core {
15+
16+
// Exporting symbols that depends on the standard C++ library is considered
17+
// safe.
18+
// https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-2-c4275?view=msvc-170&redirectedfrom=MSDN
19+
#if defined(_MSC_VER)
20+
#pragma warning(push)
21+
#pragma warning(disable : 4251)
22+
#endif
23+
24+
/// @ingroup uritemplate
25+
/// A literal string segment in a URI Template
26+
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenLiteral {
27+
std::string_view value;
28+
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
29+
char delimiter) const noexcept -> std::size_t;
30+
};
31+
32+
/// @ingroup uritemplate
33+
/// A variable specification within a URI Template expression
34+
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateVariableSpecification {
35+
std::string_view name;
36+
// As per the RFC, the range is 1-9999. 0 means "no prefix length"
37+
std::uint16_t length{0};
38+
bool explode{false};
39+
};
40+
41+
/// @ingroup uritemplate
42+
/// A simple string variable expansion {var} in a URI Template (Level 1)
43+
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenVariable {
44+
std::vector<URITemplateVariableSpecification> variables;
45+
static constexpr char separator = ',';
46+
static constexpr bool named = false;
47+
static constexpr bool allow_reserved = false;
48+
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
49+
char delimiter) const noexcept -> std::size_t;
50+
};
51+
52+
/// @ingroup uritemplate
53+
/// A reserved expansion {+var} in a URI Template (Level 2)
54+
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenReservedExpansion {
55+
std::vector<URITemplateVariableSpecification> variables;
56+
static constexpr char op = '+';
57+
static constexpr char separator = ',';
58+
static constexpr bool named = false;
59+
static constexpr bool allow_reserved = true;
60+
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
61+
char delimiter) const noexcept -> std::size_t;
62+
};
63+
64+
/// @ingroup uritemplate
65+
/// A fragment expansion {#var} in a URI Template (Level 2)
66+
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenFragmentExpansion {
67+
std::vector<URITemplateVariableSpecification> variables;
68+
static constexpr char op = '#';
69+
static constexpr char separator = ',';
70+
static constexpr char prefix = '#';
71+
static constexpr bool named = false;
72+
static constexpr bool allow_reserved = true;
73+
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
74+
char delimiter) const noexcept -> std::size_t;
75+
};
76+
77+
/// @ingroup uritemplate
78+
/// A label expansion {.var} in a URI Template (Level 3)
79+
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenLabelExpansion {
80+
std::vector<URITemplateVariableSpecification> variables;
81+
static constexpr char op = '.';
82+
static constexpr char separator = '.';
83+
static constexpr char prefix = '.';
84+
static constexpr bool named = false;
85+
static constexpr bool allow_reserved = false;
86+
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
87+
char delimiter) const noexcept -> std::size_t;
88+
};
89+
90+
/// @ingroup uritemplate
91+
/// A path expansion {/var} in a URI Template (Level 3)
92+
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenPathExpansion {
93+
std::vector<URITemplateVariableSpecification> variables;
94+
static constexpr char op = '/';
95+
static constexpr char separator = '/';
96+
static constexpr char prefix = '/';
97+
static constexpr bool named = false;
98+
static constexpr bool allow_reserved = false;
99+
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
100+
char delimiter) const noexcept -> std::size_t;
101+
};
102+
103+
/// @ingroup uritemplate
104+
/// A path parameter expansion {;var} in a URI Template (Level 3)
105+
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT
106+
URITemplateTokenPathParameterExpansion {
107+
std::vector<URITemplateVariableSpecification> variables;
108+
static constexpr char op = ';';
109+
static constexpr char separator = ';';
110+
static constexpr char prefix = ';';
111+
static constexpr bool named = true;
112+
static constexpr bool allow_reserved = false;
113+
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
114+
char delimiter) const noexcept -> std::size_t;
115+
};
116+
117+
/// @ingroup uritemplate
118+
/// A query expansion {?var} in a URI Template (Level 3)
119+
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT URITemplateTokenQueryExpansion {
120+
std::vector<URITemplateVariableSpecification> variables;
121+
static constexpr char op = '?';
122+
static constexpr char separator = '&';
123+
static constexpr char prefix = '?';
124+
static constexpr bool named = true;
125+
static constexpr bool allow_reserved = false;
126+
static constexpr char empty_suffix = '=';
127+
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
128+
char delimiter) const noexcept -> std::size_t;
129+
};
130+
131+
/// @ingroup uritemplate
132+
/// A query continuation expansion {&var} in a URI Template (Level 3)
133+
struct SOURCEMETA_CORE_URITEMPLATE_EXPORT
134+
URITemplateTokenQueryContinuationExpansion {
135+
std::vector<URITemplateVariableSpecification> variables;
136+
static constexpr char op = '&';
137+
static constexpr char separator = '&';
138+
static constexpr char prefix = '&';
139+
static constexpr bool named = true;
140+
static constexpr bool allow_reserved = false;
141+
static constexpr char empty_suffix = '=';
142+
[[nodiscard]] auto match(std::string_view uri, std::size_t position,
143+
char delimiter) const noexcept -> std::size_t;
144+
};
145+
146+
#if defined(_MSC_VER)
147+
#pragma warning(pop)
148+
#endif
149+
150+
/// @ingroup uritemplate
151+
/// A token in a parsed URI Template
152+
using URITemplateToken = std::variant<
153+
URITemplateTokenLiteral, URITemplateTokenVariable,
154+
URITemplateTokenReservedExpansion, URITemplateTokenFragmentExpansion,
155+
URITemplateTokenLabelExpansion, URITemplateTokenPathExpansion,
156+
URITemplateTokenPathParameterExpansion, URITemplateTokenQueryExpansion,
157+
URITemplateTokenQueryContinuationExpansion>;
158+
159+
} // namespace sourcemeta::core
160+
161+
#endif

src/core/uritemplate/uritemplate.cc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,17 @@ auto URITemplate::empty() const noexcept -> bool {
5858
return this->tokens_.empty();
5959
}
6060

61-
auto URITemplate::at(const std::size_t index) const
62-
-> const URITemplateToken & {
61+
auto URITemplate::at(const std::size_t index) const & -> const
62+
URITemplateToken & {
6363
assert(index < this->tokens_.size());
6464
return this->tokens_[index];
6565
}
6666

67+
auto URITemplate::at(const std::size_t index) && -> URITemplateToken {
68+
assert(index < this->tokens_.size());
69+
return std::move(this->tokens_[index]);
70+
}
71+
6772
auto URITemplate::begin() const noexcept
6873
-> std::vector<URITemplateToken>::const_iterator {
6974
return this->tokens_.cbegin();

0 commit comments

Comments
 (0)